am 7a6ccb87: Merge "Remote volume changes" into klp-dev
* commit '7a6ccb87290f12203e00cbddcffc2fbee35cebd3':
Remote volume changes
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 680e73a..d652cae 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1572,6 +1572,24 @@
/**
* @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.
* @return true if the top of the audio focus stack requested focus
* with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 79814d1..1f5fefd 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -751,6 +751,26 @@
///////////////////////////////////////////////////////////////////////////
// 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) {
@@ -763,10 +783,10 @@
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);
}
}
@@ -2612,6 +2632,17 @@
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()) {
@@ -2624,23 +2655,22 @@
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 (DEBUG_VOL)
- Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default");
- return AudioSystem.STREAM_RING;
+ } 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;
@@ -2666,14 +2696,17 @@
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");
- return 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 {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 8c05089..2f08325 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -37,6 +37,8 @@
void adjustVolume(int direction, int flags, String callingPackage);
+ boolean isLocalOrRemoteMusicActive();
+
oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
String callingPackage);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 448925b..ec70314 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -42,6 +42,7 @@
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;
@@ -3647,7 +3648,9 @@
}
/**
- * @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);
@@ -3655,7 +3658,7 @@
Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
return false;
}
- return am.isMusicActive();
+ return am.isLocalOrRemoteMusicActive();
}
/**
@@ -3668,19 +3671,28 @@
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();
- audioService.adjustStreamVolume(stream,
- keycode == KeyEvent.KEYCODE_VOLUME_UP
- ? AudioManager.ADJUST_RAISE
- : AudioManager.ADJUST_LOWER,
- 0,
- mContext.getOpPackageName());
+ 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();
}