Loading media/java/android/media/AudioManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,24 @@ public class AudioManager { return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); } /** * @hide * Checks whether any local or remote media playback is active. * Local playback refers to playback for instance on the device's speakers or wired headphones. * Remote playback refers to playback for instance on a wireless display mirroring the * devices's, or on a device using a Cast-like protocol. * @return true if media playback, from which the device is aware, is active. */ public boolean isLocalOrRemoteMusicActive() { IAudioService service = getService(); try { return service.isLocalOrRemoteMusicActive(); } catch (RemoteException e) { Log.e(TAG, "Dead object in isLocalOrRemoteMusicActive()", e); return false; } } /** * @hide * Checks whether the current audio focus is exclusive. Loading media/java/android/media/AudioService.java +56 −23 Original line number Diff line number Diff line Loading @@ -751,6 +751,26 @@ public class AudioService extends IAudioService.Stub { /////////////////////////////////////////////////////////////////////////// // IPC methods /////////////////////////////////////////////////////////////////////////// /** @see AudioManager#isLocalOrRemoteMusicActive() */ public boolean isLocalOrRemoteMusicActive() { if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { // local / wired / BT playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): local"); return true; } if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { // remote "cast-like" playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): has PLAYBACK_TYPE_REMOTE"); return true; } if (AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0)) { // remote submix playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): remote submix"); return true; } if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): no"); return false; } /** @see AudioManager#adjustVolume(int, int) */ public void adjustVolume(int direction, int flags, String callingPackage) { Loading @@ -763,10 +783,10 @@ public class AudioService extends IAudioService.Stub { public void adjustLocalOrRemoteStreamVolume(int streamType, int direction, String callingPackage) { if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")"); if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0); } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0, callingPackage); } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0); } } Loading Loading @@ -2612,6 +2632,17 @@ public class AudioService extends IAudioService.Stub { return (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION); } /** * For code clarity for getActiveStreamType(int) * @param delay_ms max time since last STREAM_MUSIC activity to consider * @return true if STREAM_MUSIC is active in streams handled by AudioFlinger now or * in the last "delay_ms" ms. */ private boolean isAfMusicActiveRecently(int delay_ms) { return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, delay_ms) || AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, delay_ms); } private int getActiveStreamType(int suggestedStreamType) { if (mVoiceCapable) { if (isInCommunication()) { Loading @@ -2624,23 +2655,22 @@ public class AudioService extends IAudioService.Stub { return AudioSystem.STREAM_VOICE_CALL; } } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control // volume can have priority over STREAM_MUSIC if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); return AudioSystem.STREAM_RING; } } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { } else if (isAfMusicActiveRecently(0)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; Loading @@ -2666,14 +2696,17 @@ public class AudioService extends IAudioService.Stub { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); return AudioSystem.STREAM_NOTIFICATION; } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control // volume can have priority over STREAM_MUSIC if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); return AudioSystem.STREAM_MUSIC; } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default"); if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default"); return AudioSystem.STREAM_MUSIC; } } else { Loading media/java/android/media/IAudioService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ interface IAudioService { void adjustVolume(int direction, int flags, String callingPackage); boolean isLocalOrRemoteMusicActive(); oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction, String callingPackage); Loading policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +23 −11 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioService; import android.media.Ringtone; import android.media.RingtoneManager; Loading Loading @@ -3647,7 +3648,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** * @return Whether music is being played right now. * @return Whether music is being played right now "locally" (e.g. on the device's speakers * or wired headphones) or "remotely" (e.g. on a device using the Cast protocol and * controlled by this device, or through remote submix). */ boolean isMusicActive() { final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); Loading @@ -3655,7 +3658,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Log.w(TAG, "isMusicActive: couldn't get AudioManager reference"); return false; } return am.isMusicActive(); return am.isLocalOrRemoteMusicActive(); } /** Loading @@ -3668,19 +3671,28 @@ public class PhoneWindowManager implements WindowManagerPolicy { return; } try { // since audio is playing, we shouldn't have to hold a wake lock // when audio is playing locally, we shouldn't have to hold a wake lock // during the call, but we do it as a precaution for the rare possibility // that the music stops right before we call this // that the music stops right before we call this. // Otherwise we might also be in a remote playback case. // TODO: Actually handle MUTE. mBroadcastWakeLock.acquire(); if (stream == AudioSystem.STREAM_MUSIC) { audioService.adjustLocalOrRemoteStreamVolume(stream, keycode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, mContext.getOpPackageName()); } else { audioService.adjustStreamVolume(stream, keycode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, 0, mContext.getOpPackageName()); } } catch (RemoteException e) { Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e); Log.w(TAG, "IAudioService.adjust*StreamVolume() threw RemoteException " + e); } finally { mBroadcastWakeLock.release(); } Loading Loading
media/java/android/media/AudioManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,24 @@ public class AudioManager { return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); } /** * @hide * Checks whether any local or remote media playback is active. * Local playback refers to playback for instance on the device's speakers or wired headphones. * Remote playback refers to playback for instance on a wireless display mirroring the * devices's, or on a device using a Cast-like protocol. * @return true if media playback, from which the device is aware, is active. */ public boolean isLocalOrRemoteMusicActive() { IAudioService service = getService(); try { return service.isLocalOrRemoteMusicActive(); } catch (RemoteException e) { Log.e(TAG, "Dead object in isLocalOrRemoteMusicActive()", e); return false; } } /** * @hide * Checks whether the current audio focus is exclusive. Loading
media/java/android/media/AudioService.java +56 −23 Original line number Diff line number Diff line Loading @@ -751,6 +751,26 @@ public class AudioService extends IAudioService.Stub { /////////////////////////////////////////////////////////////////////////// // IPC methods /////////////////////////////////////////////////////////////////////////// /** @see AudioManager#isLocalOrRemoteMusicActive() */ public boolean isLocalOrRemoteMusicActive() { if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { // local / wired / BT playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): local"); return true; } if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { // remote "cast-like" playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): has PLAYBACK_TYPE_REMOTE"); return true; } if (AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0)) { // remote submix playback active if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): remote submix"); return true; } if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): no"); return false; } /** @see AudioManager#adjustVolume(int, int) */ public void adjustVolume(int direction, int flags, String callingPackage) { Loading @@ -763,10 +783,10 @@ public class AudioService extends IAudioService.Stub { public void adjustLocalOrRemoteStreamVolume(int streamType, int direction, String callingPackage) { if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")"); if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0); } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0, callingPackage); } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0); } } Loading Loading @@ -2612,6 +2632,17 @@ public class AudioService extends IAudioService.Stub { return (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION); } /** * For code clarity for getActiveStreamType(int) * @param delay_ms max time since last STREAM_MUSIC activity to consider * @return true if STREAM_MUSIC is active in streams handled by AudioFlinger now or * in the last "delay_ms" ms. */ private boolean isAfMusicActiveRecently(int delay_ms) { return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, delay_ms) || AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, delay_ms); } private int getActiveStreamType(int suggestedStreamType) { if (mVoiceCapable) { if (isInCommunication()) { Loading @@ -2624,23 +2655,22 @@ public class AudioService extends IAudioService.Stub { return AudioSystem.STREAM_VOICE_CALL; } } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control // volume can have priority over STREAM_MUSIC if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); return AudioSystem.STREAM_RING; } } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { } else if (isAfMusicActiveRecently(0)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; Loading @@ -2666,14 +2696,17 @@ public class AudioService extends IAudioService.Stub { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); return AudioSystem.STREAM_NOTIFICATION; } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control // volume can have priority over STREAM_MUSIC if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); return AudioSystem.STREAM_MUSIC; } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default"); if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default"); return AudioSystem.STREAM_MUSIC; } } else { Loading
media/java/android/media/IAudioService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ interface IAudioService { void adjustVolume(int direction, int flags, String callingPackage); boolean isLocalOrRemoteMusicActive(); oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction, String callingPackage); Loading
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +23 −11 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioService; import android.media.Ringtone; import android.media.RingtoneManager; Loading Loading @@ -3647,7 +3648,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** * @return Whether music is being played right now. * @return Whether music is being played right now "locally" (e.g. on the device's speakers * or wired headphones) or "remotely" (e.g. on a device using the Cast protocol and * controlled by this device, or through remote submix). */ boolean isMusicActive() { final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); Loading @@ -3655,7 +3658,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Log.w(TAG, "isMusicActive: couldn't get AudioManager reference"); return false; } return am.isMusicActive(); return am.isLocalOrRemoteMusicActive(); } /** Loading @@ -3668,19 +3671,28 @@ public class PhoneWindowManager implements WindowManagerPolicy { return; } try { // since audio is playing, we shouldn't have to hold a wake lock // when audio is playing locally, we shouldn't have to hold a wake lock // during the call, but we do it as a precaution for the rare possibility // that the music stops right before we call this // that the music stops right before we call this. // Otherwise we might also be in a remote playback case. // TODO: Actually handle MUTE. mBroadcastWakeLock.acquire(); if (stream == AudioSystem.STREAM_MUSIC) { audioService.adjustLocalOrRemoteStreamVolume(stream, keycode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, mContext.getOpPackageName()); } else { audioService.adjustStreamVolume(stream, keycode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, 0, mContext.getOpPackageName()); } } catch (RemoteException e) { Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e); Log.w(TAG, "IAudioService.adjust*StreamVolume() threw RemoteException " + e); } finally { mBroadcastWakeLock.release(); } Loading