diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 24c5b41727320..2fb2f36ec9912 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -105,6 +105,7 @@ public class AudioManager { private Context mOriginalContext; private Context mApplicationContext; + private int mOriginalContextDeviceId = DEVICE_ID_DEFAULT; private @Nullable VirtualDeviceManager mVirtualDeviceManager; // Lazy initialized. private long mVolumeKeyUpTime; private static final String TAG = "AudioManager"; @@ -844,6 +845,7 @@ public class AudioManager { } private void setContext(Context context) { + mOriginalContextDeviceId = context.getDeviceId(); mApplicationContext = context.getApplicationContext(); if (mApplicationContext != null) { mOriginalContext = null; @@ -3794,7 +3796,7 @@ public class AudioManager { } /** - * Checks whether this {@link AudioManager} instance is asociated with {@link VirtualDevice} + * Checks whether this {@link AudioManager} instance is associated with {@link VirtualDevice} * configured with custom device policy for audio. If there is such device, request to play * sound effect is forwarded to {@link VirtualDeviceManager}. * @@ -3803,18 +3805,24 @@ public class AudioManager { * false otherwise. */ private boolean delegateSoundEffectToVdm(@SystemSoundEffect int effectType) { - int deviceId = getContext().getDeviceId(); - if (deviceId != DEVICE_ID_DEFAULT) { + if (hasCustomPolicyVirtualDeviceContext()) { VirtualDeviceManager vdm = getVirtualDeviceManager(); - if (vdm != null && vdm.getDevicePolicy(deviceId, POLICY_TYPE_AUDIO) - != DEVICE_POLICY_DEFAULT) { - vdm.playSoundEffect(deviceId, effectType); - return true; - } + vdm.playSoundEffect(mOriginalContextDeviceId, effectType); + return true; } return false; } + private boolean hasCustomPolicyVirtualDeviceContext() { + if (mOriginalContextDeviceId == DEVICE_ID_DEFAULT) { + return false; + } + + VirtualDeviceManager vdm = getVirtualDeviceManager(); + return vdm != null && vdm.getDevicePolicy(mOriginalContextDeviceId, POLICY_TYPE_AUDIO) + != DEVICE_POLICY_DEFAULT; + } + /** * Load Sound effects. * This method must be called when sound effects are enabled. @@ -4513,6 +4521,16 @@ public class AudioManager { throw new IllegalArgumentException( "Illegal null audio policy when locking audio focus"); } + + if (hasCustomPolicyVirtualDeviceContext()) { + // If the focus request was made within context associated with VirtualDevice + // configured with custom device policy for audio, bypass audio service focus handling. + // The custom device policy for audio means that audio associated with this device + // is likely rerouted to VirtualAudioDevice and playback on the VirtualAudioDevice + // shouldn't affect non-virtual audio tracks (and vice versa). + return AUDIOFOCUS_REQUEST_GRANTED; + } + registerAudioFocusRequest(afr); final IAudioService service = getService(); final int status; @@ -4785,16 +4803,19 @@ public class AudioManager { @SuppressLint("RequiresPermission") // no permission enforcement, but only "undoes" what would // have been done by a matching requestAudioFocus public int abandonAudioFocus(OnAudioFocusChangeListener l, AudioAttributes aa) { - int status = AUDIOFOCUS_REQUEST_FAILED; + if (hasCustomPolicyVirtualDeviceContext()) { + // If this AudioManager instance is running within VirtualDevice context configured + // with custom device policy for audio, the audio focus handling is bypassed. + return AUDIOFOCUS_REQUEST_GRANTED; + } unregisterAudioFocusRequest(l); final IAudioService service = getService(); try { - status = service.abandonAudioFocus(mAudioFocusDispatcher, + return service.abandonAudioFocus(mAudioFocusDispatcher, getIdForAudioFocusListener(l), aa, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - return status; } //====================================================================