am 7a6ccb87: Merge "Remote volume changes" into klp-dev

* commit '7a6ccb87290f12203e00cbddcffc2fbee35cebd3':
  Remote volume changes
This commit is contained in:
Jean-Michel Trivi
2013-10-11 14:14:44 -07:00
committed by Android Git Automerger
4 changed files with 99 additions and 34 deletions

View File

@ -1570,6 +1570,24 @@ public class AudioManager {
return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); 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 * @hide
* Checks whether the current audio focus is exclusive. * Checks whether the current audio focus is exclusive.

View File

@ -751,6 +751,26 @@ public class AudioService extends IAudioService.Stub {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// IPC methods // 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) */ /** @see AudioManager#adjustVolume(int, int) */
public void adjustVolume(int direction, int flags, String callingPackage) { public void adjustVolume(int direction, int flags, String callingPackage) {
@ -763,10 +783,10 @@ public class AudioService extends IAudioService.Stub {
public void adjustLocalOrRemoteStreamVolume(int streamType, int direction, public void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
String callingPackage) { String callingPackage) {
if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")"); if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")");
if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0);
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0, callingPackage); 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 @@ public class AudioService extends IAudioService.Stub {
return (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION); 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) { private int getActiveStreamType(int suggestedStreamType) {
if (mVoiceCapable) { if (mVoiceCapable) {
if (isInCommunication()) { if (isInCommunication()) {
@ -2624,23 +2655,22 @@ public class AudioService extends IAudioService.Stub {
return AudioSystem.STREAM_VOICE_CALL; return AudioSystem.STREAM_VOICE_CALL;
} }
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
// Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) {
// 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 (DEBUG_VOL) if (DEBUG_VOL)
Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active");
return AudioSystem.STREAM_MUSIC; return AudioSystem.STREAM_MUSIC;
} else { } else
if (DEBUG_VOL) if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC))
Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); {
return AudioSystem.STREAM_RING; 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) if (DEBUG_VOL)
Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active");
return AudioSystem.STREAM_MUSIC; return AudioSystem.STREAM_MUSIC;
@ -2666,14 +2696,17 @@ public class AudioService extends IAudioService.Stub {
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
return AudioSystem.STREAM_NOTIFICATION; return AudioSystem.STREAM_NOTIFICATION;
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) {
// Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC");
// volume can have priority over STREAM_MUSIC return AudioSystem.STREAM_MUSIC;
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); } else
return STREAM_REMOTE_MUSIC; if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC))
{
if (DEBUG_VOL)
Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC");
return STREAM_REMOTE_MUSIC;
} else { } else {
if (DEBUG_VOL) if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default");
Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default");
return AudioSystem.STREAM_MUSIC; return AudioSystem.STREAM_MUSIC;
} }
} else { } else {

View File

@ -37,6 +37,8 @@ interface IAudioService {
void adjustVolume(int direction, int flags, String callingPackage); void adjustVolume(int direction, int flags, String callingPackage);
boolean isLocalOrRemoteMusicActive();
oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction, oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
String callingPackage); String callingPackage);

View File

@ -42,6 +42,7 @@ import android.database.ContentObserver;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Rect; import android.graphics.Rect;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IAudioService; import android.media.IAudioService;
import android.media.Ringtone; import android.media.Ringtone;
import android.media.RingtoneManager; import android.media.RingtoneManager;
@ -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() { boolean isMusicActive() {
final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
@ -3655,7 +3658,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Log.w(TAG, "isMusicActive: couldn't get AudioManager reference"); Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
return false; return false;
} }
return am.isMusicActive(); return am.isLocalOrRemoteMusicActive();
} }
/** /**
@ -3668,19 +3671,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return; return;
} }
try { 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 // 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. // TODO: Actually handle MUTE.
mBroadcastWakeLock.acquire(); mBroadcastWakeLock.acquire();
audioService.adjustStreamVolume(stream, if (stream == AudioSystem.STREAM_MUSIC) {
keycode == KeyEvent.KEYCODE_VOLUME_UP audioService.adjustLocalOrRemoteStreamVolume(stream,
? AudioManager.ADJUST_RAISE keycode == KeyEvent.KEYCODE_VOLUME_UP
: AudioManager.ADJUST_LOWER, ? AudioManager.ADJUST_RAISE
0, : AudioManager.ADJUST_LOWER,
mContext.getOpPackageName()); mContext.getOpPackageName());
} else {
audioService.adjustStreamVolume(stream,
keycode == KeyEvent.KEYCODE_VOLUME_UP
? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER,
0,
mContext.getOpPackageName());
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e); Log.w(TAG, "IAudioService.adjust*StreamVolume() threw RemoteException " + e);
} finally { } finally {
mBroadcastWakeLock.release(); mBroadcastWakeLock.release();
} }