Skip to content

macOS: "Audio Input In Use" / "Active Audio Input" never activate — regression in 2026.9.0, works in 2026.7.1 #5635

Description

@mattsign

Bug report — ready to paste into github.com/home-assistant/iOS/issues/new

Title:

macOS: "Audio Input In Use" / "Active Audio Input" never activate (regression from #5158 — kAudioDevicePropertyDeviceIsRunningSomewhere is not scope-aware)


Environment

   
App version 2026.9.0 (2026.2874)
macOS 26.6.2 (25G83)
Hardware MacBook Pro, Mac17,2, arm64
Last known-good app version 2026.7.1 (2026.2346) — verified by downgrade
Microphone Logitech HD Pro Webcam C920 (USB, not Bluetooth)

Confirmed by downgrade: reverting to 2026.7.1 restored correct behaviour immediately — both sensors resumed tracking microphone activity with no other change made, and no reconfiguration, re-permissioning, or restart of Home Assistant.

Caveat on attribution: I upgraded 2026.7.1 → 2026.9.0 directly and downgraded straight back, so I have not bisected 2026.7.3 or 2026.8.0. What is directly established is that 2026.7.1 works and 2026.9.0 does not; pinning the cause to #5158 specifically comes from the timeline plus the code change.

Suggested fix

#5158 was fixing a real bug (#3091Audio Output In Use remaining On after playback stopped), so a straight revert would reintroduce that. Two directions that avoid the scope problem:

  1. Observe on kAudioObjectPropertyScopeGlobal (as before) and disambiguate direction from the device's stream configuration — i.e. whether the device has input streams (kAudioDevicePropertyStreams in kAudioObjectPropertyScopeInput) — rather than from the scope of a global property.

  2. Use per-process state for direction: kAudioHardwarePropertyProcessObjectList + kAudioProcessPropertyIsRunningInput / IsRunningOutput (macOS 14+) gives true per-direction, per-process activity.

⚠️ One trap worth knowing if you take route 2: on macOS 26, property listeners on kAudioProcessPropertyIsRunningInput / IsRunningOutput register successfully but never fire — I confirmed this on 26.6.2, and it matches the unanswered report in Apple Developer Forums thread 770348. Reading those properties works; observing them does not. So the workable shape is: trigger on the device-global property, then read per-process state for direction and attribution.

Also worth noting: a listener on kAudioHardwarePropertyProcessObjectList does fire, but too early to attribute — the process object is created before IO starts, so the running flags are still false at callback time.

Impact

Any automation triggered by macOS microphone activity is silently dead. There's no error and no unavailable state — the sensor simply reports false forever, so it fails silently rather than visibly.

# Bug report — ready to paste into github.com/home-assistant/iOS/issues/new

Title:

macOS: "Audio Input In Use" / "Active Audio Input" never activate (regression from #5158 — kAudioDevicePropertyDeviceIsRunningSomewhere is not scope-aware)


Environment

App version 2026.9.0 (2026.2874)
macOS 26.6.2 (25G83)
Hardware MacBook Pro, Mac17,2, arm64
Last known-good app version 2026.7.1 (2026.2346) — verified by downgrade
Microphone Logitech HD Pro Webcam C920 (USB, not Bluetooth)

What happens

On macOS, Audio Input In Use stays false and Active Audio Input stays Inactive no matter what uses the microphone — dictation apps, video calls, anything.

This is not a configuration problem:

  • Both sensors are enabled in Settings → Sensors and are reporting (false / Inactive, not unavailable).
  • The app is connected and every other enabled sensor updates normally (App Version, Camera In Use, etc.).
  • Toggling the sensors off/on, restarting the app, and restarting the Mac all change nothing.

What I expected

Audio Input In Usetrue and Active Audio Input → the device name, while the mic is in use. This worked correctly on 2026.7.1.

Steps to reproduce

  1. macOS, app 2026.9.0. Enable Audio Input In Use and Active Audio Input.
  2. Use the microphone in any app for ~10 seconds.
  3. Observe both sensors in Settings → Sensors (or in Home Assistant). Neither changes.

Evidence that macOS is reporting the activity correctly

CoreAudio's own session log shows the microphone start and stop being reported normally, correctly attributed to the app using it. Captured with:

/usr/bin/log stream --level debug --style compact \
  --predicate 'subsystem == "com.apple.coreaudio" AND category == "as_server"'
14:53:32.628  audiomxd  [com.apple.coreaudio:as_server] AVAudioSessionXPCServer.mm:2171
  {"action":"update_running_state","session":{"ID":"0x29a081","name":"Wispr Flow Helpe(67276)"},
   "details":{"implicit_category":"Record","input_running":true,"output_running":false}}

14:53:43.124  audiomxd  [com.apple.coreaudio:as_server] AVAudioSessionXPCServer.mm:2171
  {"action":"update_running_state","session":{"ID":"0x29a081","name":"Wispr Flow Helpe(67276)"},
   "details":{"implicit_category":"MediaPlayback","input_running":false,"output_running":true}}

input_running goes truefalse across a 10.5-second microphone session. The companion sensor stayed false throughout. The OS layer is healthy; the app is not observing it.

Likely root cause

I believe this is a regression from #5158 — "Use scoped CoreAudio running state for macOS input/output sensors" (merged 2026-07-20), which changed observation to:

audioInputs.forEach  { updateSignaler.addCoreAudioObserver(for: $0.id, property: .isInputRunningSomewhere) }
audioOutputs.forEach { updateSignaler.addCoreAudioObserver(for: $0.id, property: .isOutputRunningSomewhere) }

…where those are kAudioDevicePropertyDeviceIsRunningSomewhere addressed with kAudioObjectPropertyScopeInput / kAudioObjectPropertyScopeOutput.

That property is device-global and has no per-direction semantics. Apple's AudioHardware.h documents it as:

kAudioDevicePropertyDeviceIsRunningSomewhere — A UInt32 where 1 means that the AudioDevice is running in at least one process on the system and 0 means that it isn't running at all.

There is no input/output variant. Addressed with a directional scope, the listener registers without error but never fires, and the value reads as not-running — which matches the observed behaviour exactly. Registering the same selector with kAudioObjectPropertyScopeGlobal works correctly on this machine (verified separately with a small Swift test harness: callbacks fire on both start and stop, ~35 ms on stop, ~115 ms on start).

Timeline

Release Date Behaviour
2026.7.1 2026-07-14 ✅ works — confirmed twice (before upgrade, and again after downgrading back)
#5158 merged 2026-07-20
2026.7.3 2026-08-04 first release containing the change
2026.9.0 2026-08-31 ❌ broken

Confirmed by downgrade: reverting to 2026.7.1 restored correct behaviour immediately — both sensors resumed tracking microphone activity with no other change made, and no reconfiguration, re-permissioning, or restart of Home Assistant.

Caveat on attribution: I upgraded 2026.7.1 → 2026.9.0 directly and downgraded straight back, so I have not bisected 2026.7.3 or 2026.8.0. What is directly established is that 2026.7.1 works and 2026.9.0 does not; pinning the cause to #5158 specifically comes from the timeline plus the code change.

Suggested fix

#5158 was fixing a real bug (#3091Audio Output In Use remaining On after playback stopped), so a straight revert would reintroduce that. Two directions that avoid the scope problem:

  1. Observe on kAudioObjectPropertyScopeGlobal (as before) and disambiguate direction from the device's stream configuration — i.e. whether the device has input streams (kAudioDevicePropertyStreams in kAudioObjectPropertyScopeInput) — rather than from the scope of a global property.
  2. Use per-process state for direction: kAudioHardwarePropertyProcessObjectList + kAudioProcessPropertyIsRunningInput / IsRunningOutput (macOS 14+) gives true per-direction, per-process activity.

⚠️ One trap worth knowing if you take route 2: on macOS 26, property listeners on kAudioProcessPropertyIsRunningInput / IsRunningOutput register successfully but never fire — I confirmed this on 26.6.2, and it matches the unanswered report in [Apple Developer Forums thread 770348](https://developer.apple.com/forums/thread/770348). Reading those properties works; observing them does not. So the workable shape is: trigger on the device-global property, then read per-process state for direction and attribution.

Also worth noting: a listener on kAudioHardwarePropertyProcessObjectList does fire, but too early to attribute — the process object is created before IO starts, so the running flags are still false at callback time.

Impact

Any automation triggered by macOS microphone activity is silently dead. There's no error and no unavailable state — the sensor simply reports false forever, so it fails silently rather than visibly.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions