From b561ccedd89f92b249c06522e960b135a02107d8 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Fri, 30 Jan 2015 17:48:51 +0900 Subject: [PATCH] audio: allow audio port cache update even when audio patches contain invalidated sources/sinks When an audio device disconnects from Android, custom audio patches containing the device become invalidated. AudioManager::updateAudioPortCache() used to fail in that case, but it causes onAudioPortListUpdated() event never gets called so that the creator of the custom audio patch cannot update it. Let updateAudioPortCached() succeed even in the case so that the entity that created the audio patch can get notified. Bug: 18909299 Change-Id: If4f6ed73f69213d792117fb42aec103ae2e50b79 --- media/java/android/media/AudioManager.java | 33 ++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 67c05520bad81..240faef810d5c 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -46,9 +46,9 @@ import android.provider.Settings; import android.util.Log; import android.view.KeyEvent; -import java.util.HashMap; import java.util.ArrayList; - +import java.util.HashMap; +import java.util.Iterator; /** * AudioManager provides access to volume and ringer mode control. @@ -3650,11 +3650,13 @@ public class AudioManager { newPorts.clear(); status = AudioSystem.listAudioPorts(newPorts, portGeneration); if (status != SUCCESS) { + Log.w(TAG, "updateAudioPortCache: listAudioPorts failed"); return status; } newPatches.clear(); status = AudioSystem.listAudioPatches(newPatches, patchGeneration); if (status != SUCCESS) { + Log.w(TAG, "updateAudioPortCache: listAudioPatches failed"); return status; } } while (patchGeneration[0] != portGeneration[0]); @@ -3663,20 +3665,35 @@ public class AudioManager { for (int j = 0; j < newPatches.get(i).sources().length; j++) { AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j], newPorts); - if (portCfg == null) { - return ERROR; - } newPatches.get(i).sources()[j] = portCfg; } for (int j = 0; j < newPatches.get(i).sinks().length; j++) { AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j], newPorts); - if (portCfg == null) { - return ERROR; - } newPatches.get(i).sinks()[j] = portCfg; } } + for (Iterator i = newPatches.iterator(); i.hasNext(); ) { + AudioPatch newPatch = i.next(); + boolean hasInvalidPort = false; + for (AudioPortConfig portCfg : newPatch.sources()) { + if (portCfg == null) { + hasInvalidPort = true; + break; + } + } + for (AudioPortConfig portCfg : newPatch.sinks()) { + if (portCfg == null) { + hasInvalidPort = true; + break; + } + } + if (hasInvalidPort) { + // Temporarily remove patches with invalid ports. One who created the patch + // is responsible for dealing with the port change. + i.remove(); + } + } sAudioPortsCached = newPorts; sAudioPatchesCached = newPatches;