CVE-2026-58841 AI-generated analysis
platform/frameworks/base, services/companion (virtual device audio, VirtualAudioController)
VirtualAudioController.startListening now registers mAudioPlaybackDetector unconditionally instead of only when an IAudioConfigChangedCallback is supplied, so per the commit message the deferred silence-injection policy update recovers correctly when no config-changed callback is provided.
Root cause
In services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java, startListening() registered both mAudioPlaybackDetector and mAudioRecordingDetector inside `if (configChangedCallback != null)`. When a caller passed a null configChangedCallback, the controller was never registered with the playback detector and so did not receive playback callbacks. Per the commit message, this caused the deferred silence-injection policy update to be skipped and not recover. stopListening() unregisters both detectors unconditionally, so registration and unregistration of the playback detector were asymmetric.
How the fix works
- services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java:startListening(): the call mAudioPlaybackDetector.register(/* callback= */ this) is moved out of the `if (configChangedCallback != null)` block. It now runs unconditionally, right after mRunningAppUids and mPlayingAppUids are cleared under mLock.
- The `if (configChangedCallback != null)` block is kept and now only guards mAudioRecordingDetector.register(/* callback= */ this). The commit message says the recording detector should be registered only when configChangedCallback is provided.
- Single-file change (1 insertion, 1 deletion); no other function is changed. stopListening() is unchanged and already unregisters both detectors unconditionally.
Completeness
- Covers the only registration site shown: startListening() in VirtualAudioController. The playback detector is now registered regardless of configChangedCallback.
- mAudioRecordingDetector.register remains conditional on configChangedCallback != null, as the commit message describes. The material does not show whether recording detection feeds any policy decision.
- The material does not show the playback callback handler or the policy update logic, so other possible skip conditions cannot be judged from the diff.
Behavior changes
- Every startListening() call now registers VirtualAudioController as a callback with AudioPlaybackDetector, including when configChangedCallback is null, so it now receives playback callbacks in that case.
- No API, error code or timeout changes. stopListening() and the recording detector's registration behavior are unchanged.
Per major
- Android 14: same fix: platform/frameworks/base 8ded15ca0499 in android-security-14.0.0_r29, the same one-line move (hunk starts at line 94). Patched region fully present at android-security-14.0.0_r30 (5/5 lines).
- Android 15: same fix: platform/frameworks/base a46c94ad2ccc in android-security-15.0.0_r17, identical diff (hunk starts at line 102). Patched region fully present at android-security-15.0.0_r18 (5/5 lines).
- Android 16: same fix: platform/frameworks/base 3184e06e737a in android-security-16.0.0_r8, identical diff (hunk starts at line 100). Patched region fully present at android-security-16.0.0_r9 (5/5 lines).
- Android 17: same fix: platform/frameworks/base 1412cbcc0c10 in android-security-17.0.0_r1, identical diff (hunk starts at line 102; the class header context line differs slightly). Patched region fully present at android-security-17.0.0_r2 (5/5 lines).
Unknowns
- The playback callback implementation and the deferred silence-injection update logic are not shown. The policy effect of the missed callbacks is known only from the commit message.
- The material does not show which callers pass a null IAudioConfigChangedCallback to startListening().
- The material does not show whether keeping mAudioRecordingDetector registration conditional has any policy consequence.