Fix issue 3371080
Modified default volume control logic in AudioService: 1 IN_CALL volume if in video/audio chat 2 NOTIFICATION if notification is playing or was playing less than 5s ago. 3 MUSIC Modified silent mode: - now also affect MUSIC stream type - entering silent mode when VOL- hard key is pressed once while selected stream volume is already at 0 (except for VOICE_CALL stream). - exiting silent mode when pressing VOL+ hard key while in silent mode Play sound FX (audible selections, keyboard clicks) at a fixed volume. Modified audio framework: - isStreamActive() method now implemented in AudioPolicyManagerBase (previously AudioFlinger) - iStreamActive() now specifies a time window during which the stream is considered active after it actually stopped. Change-Id: I7e5a0724099450b9fc90825224180ac97322785f
This commit is contained in:
@ -64,10 +64,10 @@ android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static jboolean
|
static jboolean
|
||||||
android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream)
|
android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
|
||||||
{
|
{
|
||||||
bool state = false;
|
bool state = false;
|
||||||
AudioSystem::isStreamActive(stream, &state);
|
AudioSystem::isStreamActive(stream, &state, inPastMs);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ static JNINativeMethod gMethods[] = {
|
|||||||
{"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
|
{"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
|
||||||
{"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
|
{"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
|
||||||
{"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
|
{"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
|
||||||
{"isStreamActive", "(I)Z", (void *)android_media_AudioSystem_isStreamActive},
|
{"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
|
||||||
{"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
|
{"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
|
||||||
{"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
|
{"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
|
||||||
{"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
|
{"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
|
||||||
|
@ -204,8 +204,9 @@ public:
|
|||||||
// set audio mode in audio hardware (see AudioSystem::audio_mode)
|
// set audio mode in audio hardware (see AudioSystem::audio_mode)
|
||||||
static status_t setMode(int mode);
|
static status_t setMode(int mode);
|
||||||
|
|
||||||
// returns true in *state if tracks are active on the specified stream
|
// returns true in *state if tracks are active on the specified stream or has been active
|
||||||
static status_t isStreamActive(int stream, bool *state);
|
// in the past inPastMs milliseconds
|
||||||
|
static status_t isStreamActive(int stream, bool *state, uint32_t inPastMs = 0);
|
||||||
|
|
||||||
// set/get audio hardware parameters. The function accepts a list of parameters
|
// set/get audio hardware parameters. The function accepts a list of parameters
|
||||||
// key value pairs in the form: key1=value1;key2=value2;...
|
// key value pairs in the form: key1=value1;key2=value2;...
|
||||||
|
@ -102,9 +102,6 @@ public:
|
|||||||
virtual status_t setMicMute(bool state) = 0;
|
virtual status_t setMicMute(bool state) = 0;
|
||||||
virtual bool getMicMute() const = 0;
|
virtual bool getMicMute() const = 0;
|
||||||
|
|
||||||
// is any track active on this stream?
|
|
||||||
virtual bool isStreamActive(int stream) const = 0;
|
|
||||||
|
|
||||||
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
|
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
|
||||||
virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
|
virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ public:
|
|||||||
int session,
|
int session,
|
||||||
int id) = 0;
|
int id) = 0;
|
||||||
virtual status_t unregisterEffect(int id) = 0;
|
virtual status_t unregisterEffect(int id) = 0;
|
||||||
|
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,10 +394,10 @@ public class AudioManager {
|
|||||||
*/
|
*/
|
||||||
adjustSuggestedStreamVolume(
|
adjustSuggestedStreamVolume(
|
||||||
keyCode == KeyEvent.KEYCODE_VOLUME_UP
|
keyCode == KeyEvent.KEYCODE_VOLUME_UP
|
||||||
? AudioManager.ADJUST_RAISE
|
? ADJUST_RAISE
|
||||||
: AudioManager.ADJUST_LOWER,
|
: ADJUST_LOWER,
|
||||||
stream,
|
stream,
|
||||||
AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
|
FLAG_SHOW_UI | FLAG_VIBRATE);
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
||||||
// TODO: Actually handle MUTE.
|
// TODO: Actually handle MUTE.
|
||||||
@ -416,7 +416,11 @@ public class AudioManager {
|
|||||||
* Play a sound. This is done on key up since we don't want the
|
* Play a sound. This is done on key up since we don't want the
|
||||||
* sound to play when a user holds down volume down to mute.
|
* sound to play when a user holds down volume down to mute.
|
||||||
*/
|
*/
|
||||||
adjustSuggestedStreamVolume(ADJUST_SAME, stream, FLAG_PLAY_SOUND);
|
adjustSuggestedStreamVolume(
|
||||||
|
ADJUST_SAME,
|
||||||
|
stream,
|
||||||
|
FLAG_PLAY_SOUND);
|
||||||
|
|
||||||
mVolumeKeyUpTime = SystemClock.uptimeMillis();
|
mVolumeKeyUpTime = SystemClock.uptimeMillis();
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
||||||
@ -554,6 +558,21 @@ public class AudioManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last audible volume before stream was muted.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int getLastAudibleStreamVolume(int streamType) {
|
||||||
|
IAudioService service = getService();
|
||||||
|
try {
|
||||||
|
return service.getLastAudibleStreamVolume(streamType);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Dead object in getLastAudibleStreamVolume", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the ringer mode.
|
* Sets the ringer mode.
|
||||||
* <p>
|
* <p>
|
||||||
@ -648,6 +667,21 @@ public class AudioManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get stream mute state.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isStreamMute(int streamType) {
|
||||||
|
IAudioService service = getService();
|
||||||
|
try {
|
||||||
|
return service.isStreamMute(streamType);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Dead object in isStreamMute", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a particular type should vibrate according to user
|
* Returns whether a particular type should vibrate according to user
|
||||||
* settings and the current ringer mode.
|
* settings and the current ringer mode.
|
||||||
@ -1124,7 +1158,7 @@ public class AudioManager {
|
|||||||
* @return true if any music tracks are active.
|
* @return true if any music tracks are active.
|
||||||
*/
|
*/
|
||||||
public boolean isMusicActive() {
|
public boolean isMusicActive() {
|
||||||
return AudioSystem.isStreamActive(STREAM_MUSIC);
|
return AudioSystem.isStreamActive(STREAM_MUSIC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -284,6 +284,15 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
private SoundPoolListenerThread mSoundPoolListenerThread;
|
private SoundPoolListenerThread mSoundPoolListenerThread;
|
||||||
// message looper for SoundPool listener
|
// message looper for SoundPool listener
|
||||||
private Looper mSoundPoolLooper = null;
|
private Looper mSoundPoolLooper = null;
|
||||||
|
// default volume applied to sound played with playSoundEffect()
|
||||||
|
private static final int SOUND_EFFECT_DEFAULT_VOLUME_DB = -20;
|
||||||
|
// volume applied to sound played with playSoundEffect() read from ro.config.sound_fx_volume
|
||||||
|
private int SOUND_EFFECT_VOLUME_DB;
|
||||||
|
// getActiveStreamType() will return STREAM_NOTIFICATION during this period after a notification
|
||||||
|
// stopped
|
||||||
|
private static final int NOTIFICATION_VOLUME_DELAY_MS = 5000;
|
||||||
|
// previous volume adjustment direction received by checkForRingerModeChange()
|
||||||
|
private int mPrevVolDirection = AudioManager.ADJUST_SAME;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Construction
|
// Construction
|
||||||
@ -301,6 +310,10 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
"ro.config.vc_call_vol_steps",
|
"ro.config.vc_call_vol_steps",
|
||||||
MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
|
MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
|
||||||
|
|
||||||
|
SOUND_EFFECT_VOLUME_DB = SystemProperties.getInt(
|
||||||
|
"ro.config.sound_fx_volume",
|
||||||
|
SOUND_EFFECT_DEFAULT_VOLUME_DB);
|
||||||
|
|
||||||
mVolumePanel = new VolumePanel(context, this);
|
mVolumePanel = new VolumePanel(context, this);
|
||||||
mSettingsObserver = new SettingsObserver();
|
mSettingsObserver = new SettingsObserver();
|
||||||
mForcedUseForComm = AudioSystem.FORCE_NONE;
|
mForcedUseForComm = AudioSystem.FORCE_NONE;
|
||||||
@ -401,14 +414,19 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
mRingerModeAffectedStreams = Settings.System.getInt(cr,
|
mRingerModeAffectedStreams = Settings.System.getInt(cr,
|
||||||
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
|
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
|
||||||
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
|
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
|
||||||
(1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
|
(1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)|
|
||||||
|
(1 << AudioSystem.STREAM_MUSIC)));
|
||||||
|
|
||||||
mMuteAffectedStreams = System.getInt(cr,
|
mMuteAffectedStreams = System.getInt(cr,
|
||||||
System.MUTE_STREAMS_AFFECTED,
|
System.MUTE_STREAMS_AFFECTED,
|
||||||
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
|
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
|
||||||
|
|
||||||
mNotificationsUseRingVolume = System.getInt(cr,
|
if (mVoiceCapable) {
|
||||||
Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);
|
mNotificationsUseRingVolume = System.getInt(cr,
|
||||||
|
Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);
|
||||||
|
} else {
|
||||||
|
mNotificationsUseRingVolume = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (mNotificationsUseRingVolume == 1) {
|
if (mNotificationsUseRingVolume == 1) {
|
||||||
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
|
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
|
||||||
@ -465,8 +483,10 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
|
|
||||||
// If either the client forces allowing ringer modes for this adjustment,
|
// If either the client forces allowing ringer modes for this adjustment,
|
||||||
// or the stream type is one that is affected by ringer modes
|
// or the stream type is one that is affected by ringer modes
|
||||||
if ((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0
|
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
|
||||||
|| streamType == AudioSystem.STREAM_RING) {
|
(!mVoiceCapable && streamType != AudioSystem.STREAM_VOICE_CALL &&
|
||||||
|
streamType != AudioSystem.STREAM_BLUETOOTH_SCO) ||
|
||||||
|
(mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
|
||||||
// Check if the ringer mode changes with this volume adjustment. If
|
// Check if the ringer mode changes with this volume adjustment. If
|
||||||
// it does, it will handle adjusting the volume, so we won't below
|
// it does, it will handle adjusting the volume, so we won't below
|
||||||
adjustVolume = checkForRingerModeChange(oldIndex, direction);
|
adjustVolume = checkForRingerModeChange(oldIndex, direction);
|
||||||
@ -491,10 +511,8 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
}
|
}
|
||||||
index = streamState.mIndex;
|
index = streamState.mIndex;
|
||||||
}
|
}
|
||||||
// UI
|
|
||||||
mVolumePanel.postVolumeChanged(streamType, flags);
|
sendVolumeUpdate(streamType, oldIndex, index, flags);
|
||||||
// Broadcast Intent
|
|
||||||
sendVolumeUpdate(streamType, oldIndex, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see AudioManager#setStreamVolume(int, int, int) */
|
/** @see AudioManager#setStreamVolume(int, int, int) */
|
||||||
@ -509,21 +527,23 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
|
|
||||||
index = (streamState.muteCount() != 0) ? streamState.mLastAudibleIndex : streamState.mIndex;
|
index = (streamState.muteCount() != 0) ? streamState.mLastAudibleIndex : streamState.mIndex;
|
||||||
|
|
||||||
// UI, etc.
|
sendVolumeUpdate(streamType, oldIndex, index, flags);
|
||||||
mVolumePanel.postVolumeChanged(streamType, flags);
|
|
||||||
// Broadcast Intent
|
|
||||||
sendVolumeUpdate(streamType, oldIndex, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendVolumeUpdate(int streamType, int oldIndex, int index) {
|
// UI update and Broadcast Intent
|
||||||
|
private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
|
||||||
|
if (!mVoiceCapable && (streamType == AudioSystem.STREAM_RING)) {
|
||||||
|
streamType = AudioSystem.STREAM_NOTIFICATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVolumePanel.postVolumeChanged(streamType, flags);
|
||||||
|
|
||||||
oldIndex = (oldIndex + 5) / 10;
|
oldIndex = (oldIndex + 5) / 10;
|
||||||
index = (index + 5) / 10;
|
index = (index + 5) / 10;
|
||||||
|
|
||||||
Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
|
Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
|
||||||
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
|
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
|
||||||
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
|
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
|
||||||
intent.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
|
intent.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
|
||||||
|
|
||||||
mContext.sendBroadcast(intent);
|
mContext.sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,6 +595,11 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** get stream mute state. */
|
||||||
|
public boolean isStreamMute(int streamType) {
|
||||||
|
return (mStreamStates[streamType].muteCount() != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/** @see AudioManager#getStreamVolume(int) */
|
/** @see AudioManager#getStreamVolume(int) */
|
||||||
public int getStreamVolume(int streamType) {
|
public int getStreamVolume(int streamType) {
|
||||||
ensureValidStreamType(streamType);
|
ensureValidStreamType(streamType);
|
||||||
@ -587,6 +612,13 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
|
return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get last audible volume before stream was muted. */
|
||||||
|
public int getLastAudibleStreamVolume(int streamType) {
|
||||||
|
ensureValidStreamType(streamType);
|
||||||
|
return (mStreamStates[streamType].mLastAudibleIndex + 5) / 10;
|
||||||
|
}
|
||||||
|
|
||||||
/** @see AudioManager#getRingerMode() */
|
/** @see AudioManager#getRingerMode() */
|
||||||
public int getRingerMode() {
|
public int getRingerMode() {
|
||||||
return mRingerMode;
|
return mRingerMode;
|
||||||
@ -1383,8 +1415,9 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
|
|
||||||
if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
|
if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
|
||||||
// audible mode, at the bottom of the scale
|
// audible mode, at the bottom of the scale
|
||||||
if (direction == AudioManager.ADJUST_LOWER
|
if ((direction == AudioManager.ADJUST_LOWER &&
|
||||||
&& (oldIndex + 5) / 10 == 1) {
|
mPrevVolDirection != AudioManager.ADJUST_LOWER) &&
|
||||||
|
((oldIndex + 5) / 10 == 0)) {
|
||||||
// "silent mode", but which one?
|
// "silent mode", but which one?
|
||||||
newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
|
newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
|
||||||
? AudioManager.RINGER_MODE_VIBRATE
|
? AudioManager.RINGER_MODE_VIBRATE
|
||||||
@ -1411,6 +1444,8 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
adjustVolumeIndex = false;
|
adjustVolumeIndex = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPrevVolDirection = direction;
|
||||||
|
|
||||||
return adjustVolumeIndex;
|
return adjustVolumeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1439,36 +1474,61 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getActiveStreamType(int suggestedStreamType) {
|
private int getActiveStreamType(int suggestedStreamType) {
|
||||||
boolean isOffhook = false;
|
|
||||||
try {
|
|
||||||
ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
|
|
||||||
if (phone != null) isOffhook = phone.isOffhook();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Couldn't connect to phone service", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_BT_SCO) {
|
if (mVoiceCapable) {
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
|
boolean isOffhook = false;
|
||||||
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
try {
|
||||||
} else if (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION) {
|
ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
|
if (phone != null) isOffhook = phone.isOffhook();
|
||||||
return AudioSystem.STREAM_VOICE_CALL;
|
} catch (RemoteException e) {
|
||||||
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC)) {
|
Log.w(TAG, "Couldn't connect to phone service", e);
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC...");
|
}
|
||||||
return AudioSystem.STREAM_MUSIC;
|
|
||||||
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
|
if (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION) {
|
||||||
if (mVoiceCapable) {
|
if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
|
||||||
|
== AudioSystem.FORCE_BT_SCO) {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
|
||||||
|
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||||
|
} else {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
|
||||||
|
return AudioSystem.STREAM_VOICE_CALL;
|
||||||
|
}
|
||||||
|
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC...");
|
||||||
|
return AudioSystem.STREAM_MUSIC;
|
||||||
|
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING..."
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING..."
|
||||||
// + " b/c USE_DEFAULT_STREAM_TYPE...");
|
// + " b/c USE_DEFAULT_STREAM_TYPE...");
|
||||||
return AudioSystem.STREAM_RING;
|
return AudioSystem.STREAM_RING;
|
||||||
} else {
|
} else {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Returning suggested type " + suggestedStreamType);
|
||||||
|
return suggestedStreamType;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getMode() == AudioManager.MODE_IN_COMMUNICATION) {
|
||||||
|
if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
|
||||||
|
== AudioSystem.FORCE_BT_SCO) {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
|
||||||
|
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||||
|
} else {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
|
||||||
|
return AudioSystem.STREAM_VOICE_CALL;
|
||||||
|
}
|
||||||
|
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_NOTIFICATION,
|
||||||
|
NOTIFICATION_VOLUME_DELAY_MS) ||
|
||||||
|
AudioSystem.isStreamActive(AudioSystem.STREAM_RING,
|
||||||
|
NOTIFICATION_VOLUME_DELAY_MS)) {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION...");
|
||||||
|
return AudioSystem.STREAM_NOTIFICATION;
|
||||||
|
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) ||
|
||||||
|
(suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE)) {
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC "
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC "
|
||||||
// + " b/c USE_DEFAULT_STREAM_TYPE...");
|
// + " b/c USE_DEFAULT_STREAM_TYPE...");
|
||||||
return AudioSystem.STREAM_MUSIC;
|
return AudioSystem.STREAM_MUSIC;
|
||||||
|
} else {
|
||||||
|
// Log.v(TAG, "getActiveStreamType: Returning suggested type " + suggestedStreamType);
|
||||||
|
return suggestedStreamType;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Log.v(TAG, "getActiveStreamType: Returning suggested type " + suggestedStreamType);
|
|
||||||
return suggestedStreamType;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1801,13 +1861,9 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float volFloat;
|
float volFloat;
|
||||||
// use STREAM_MUSIC volume attenuated by 3 dB if volume is not specified by caller
|
// use default if volume is not specified by caller
|
||||||
if (volume < 0) {
|
if (volume < 0) {
|
||||||
// Same linear to log conversion as in native AudioSystem::linearToLog() (AudioSystem.cpp)
|
volFloat = (float)Math.pow(10, SOUND_EFFECT_VOLUME_DB/20);
|
||||||
float dBPerStep = (float)((0.5 * 100) / MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
|
|
||||||
int musicVolIndex = (mStreamStates[AudioSystem.STREAM_MUSIC].mIndex + 5) / 10;
|
|
||||||
float musicVoldB = dBPerStep * (musicVolIndex - MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
|
|
||||||
volFloat = (float)Math.pow(10, (musicVoldB - 3)/20);
|
|
||||||
} else {
|
} else {
|
||||||
volFloat = (float) volume / 1000.0f;
|
volFloat = (float) volume / 1000.0f;
|
||||||
}
|
}
|
||||||
@ -1884,7 +1940,7 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
// Force creation of new IAudioflinger interface
|
// Force creation of new IAudioflinger interface
|
||||||
if (!mMediaServerOk) {
|
if (!mMediaServerOk) {
|
||||||
Log.e(TAG, "Media server died.");
|
Log.e(TAG, "Media server died.");
|
||||||
AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC);
|
AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
|
||||||
sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SHARED_MSG, SENDMSG_NOOP, 0, 0,
|
sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SHARED_MSG, SENDMSG_NOOP, 0, 0,
|
||||||
null, 500);
|
null, 500);
|
||||||
}
|
}
|
||||||
@ -1981,21 +2037,23 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
int notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
|
int notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
|
||||||
Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
|
Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
|
||||||
1);
|
1);
|
||||||
if (notificationsUseRingVolume != mNotificationsUseRingVolume) {
|
if (mVoiceCapable) {
|
||||||
mNotificationsUseRingVolume = notificationsUseRingVolume;
|
if (notificationsUseRingVolume != mNotificationsUseRingVolume) {
|
||||||
if (mNotificationsUseRingVolume == 1) {
|
mNotificationsUseRingVolume = notificationsUseRingVolume;
|
||||||
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
|
if (mNotificationsUseRingVolume == 1) {
|
||||||
mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
|
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
|
||||||
System.VOLUME_SETTINGS[AudioSystem.STREAM_RING]);
|
mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
|
||||||
} else {
|
System.VOLUME_SETTINGS[AudioSystem.STREAM_RING]);
|
||||||
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
|
} else {
|
||||||
mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
|
STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
|
||||||
System.VOLUME_SETTINGS[AudioSystem.STREAM_NOTIFICATION]);
|
mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
|
||||||
// Persist notification volume volume as it was not persisted while aliased to ring volume
|
System.VOLUME_SETTINGS[AudioSystem.STREAM_NOTIFICATION]);
|
||||||
// and persist with no delay as there might be registered observers of the persisted
|
// Persist notification volume volume as it was not persisted while aliased to ring volume
|
||||||
// notification volume.
|
// and persist with no delay as there might be registered observers of the persisted
|
||||||
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
|
// notification volume.
|
||||||
SENDMSG_REPLACE, 1, 1, mStreamStates[AudioSystem.STREAM_NOTIFICATION], 0);
|
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
|
||||||
|
SENDMSG_REPLACE, 1, 1, mStreamStates[AudioSystem.STREAM_NOTIFICATION], 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ public class AudioSystem
|
|||||||
*
|
*
|
||||||
* return true if any track playing on this stream is active.
|
* return true if any track playing on this stream is active.
|
||||||
*/
|
*/
|
||||||
public static native boolean isStreamActive(int stream);
|
public static native boolean isStreamActive(int stream, int inPastMs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets a group generic audio configuration parameters. The use of these parameters
|
* Sets a group generic audio configuration parameters. The use of these parameters
|
||||||
|
@ -35,11 +35,15 @@ interface IAudioService {
|
|||||||
void setStreamSolo(int streamType, boolean state, IBinder cb);
|
void setStreamSolo(int streamType, boolean state, IBinder cb);
|
||||||
|
|
||||||
void setStreamMute(int streamType, boolean state, IBinder cb);
|
void setStreamMute(int streamType, boolean state, IBinder cb);
|
||||||
|
|
||||||
|
boolean isStreamMute(int streamType);
|
||||||
|
|
||||||
int getStreamVolume(int streamType);
|
int getStreamVolume(int streamType);
|
||||||
|
|
||||||
int getStreamMaxVolume(int streamType);
|
int getStreamMaxVolume(int streamType);
|
||||||
|
|
||||||
|
int getLastAudibleStreamVolume(int streamType);
|
||||||
|
|
||||||
void setRingerMode(int ringerMode);
|
void setRingerMode(int ringerMode);
|
||||||
|
|
||||||
int getRingerMode();
|
int getRingerMode();
|
||||||
|
@ -169,15 +169,6 @@ status_t AudioSystem::setMode(int mode)
|
|||||||
return af->setMode(mode);
|
return af->setMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t AudioSystem::isStreamActive(int stream, bool* state) {
|
|
||||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
|
||||||
if (af == 0) return PERMISSION_DENIED;
|
|
||||||
*state = af->isStreamActive(stream);
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
|
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
|
||||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
||||||
if (af == 0) return PERMISSION_DENIED;
|
if (af == 0) return PERMISSION_DENIED;
|
||||||
@ -702,6 +693,14 @@ status_t AudioSystem::unregisterEffect(int id)
|
|||||||
return aps->unregisterEffect(id);
|
return aps->unregisterEffect(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) {
|
||||||
|
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
|
||||||
|
if (aps == 0) return PERMISSION_DENIED;
|
||||||
|
*state = aps->isStreamActive(stream, inPastMs);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who) {
|
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who) {
|
||||||
|
@ -47,7 +47,6 @@ enum {
|
|||||||
SET_MODE,
|
SET_MODE,
|
||||||
SET_MIC_MUTE,
|
SET_MIC_MUTE,
|
||||||
GET_MIC_MUTE,
|
GET_MIC_MUTE,
|
||||||
IS_STREAM_ACTIVE,
|
|
||||||
SET_PARAMETERS,
|
SET_PARAMETERS,
|
||||||
GET_PARAMETERS,
|
GET_PARAMETERS,
|
||||||
REGISTER_CLIENT,
|
REGISTER_CLIENT,
|
||||||
@ -316,15 +315,6 @@ public:
|
|||||||
return reply.readInt32();
|
return reply.readInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isStreamActive(int stream) const
|
|
||||||
{
|
|
||||||
Parcel data, reply;
|
|
||||||
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
|
|
||||||
data.writeInt32(stream);
|
|
||||||
remote()->transact(IS_STREAM_ACTIVE, data, &reply);
|
|
||||||
return reply.readInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs)
|
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs)
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
@ -826,12 +816,6 @@ status_t BnAudioFlinger::onTransact(
|
|||||||
reply->writeInt32( getMicMute() );
|
reply->writeInt32( getMicMute() );
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
case IS_STREAM_ACTIVE: {
|
|
||||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
|
||||||
int stream = data.readInt32();
|
|
||||||
reply->writeInt32( isStreamActive(stream) );
|
|
||||||
return NO_ERROR;
|
|
||||||
} break;
|
|
||||||
case SET_PARAMETERS: {
|
case SET_PARAMETERS: {
|
||||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||||
int ioHandle = data.readInt32();
|
int ioHandle = data.readInt32();
|
||||||
|
@ -48,7 +48,8 @@ enum {
|
|||||||
GET_STRATEGY_FOR_STREAM,
|
GET_STRATEGY_FOR_STREAM,
|
||||||
GET_OUTPUT_FOR_EFFECT,
|
GET_OUTPUT_FOR_EFFECT,
|
||||||
REGISTER_EFFECT,
|
REGISTER_EFFECT,
|
||||||
UNREGISTER_EFFECT
|
UNREGISTER_EFFECT,
|
||||||
|
IS_STREAM_ACTIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
|
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
|
||||||
@ -297,6 +298,15 @@ public:
|
|||||||
return static_cast <status_t> (reply.readInt32());
|
return static_cast <status_t> (reply.readInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool isStreamActive(int stream, uint32_t inPastMs) const
|
||||||
|
{
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
|
||||||
|
data.writeInt32(stream);
|
||||||
|
data.writeInt32(inPastMs);
|
||||||
|
remote()->transact(IS_STREAM_ACTIVE, data, &reply);
|
||||||
|
return reply.readInt32();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
|
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
|
||||||
@ -517,6 +527,14 @@ status_t BnAudioPolicyService::onTransact(
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case IS_STREAM_ACTIVE: {
|
||||||
|
CHECK_INTERFACE(IAudioPolicyService, data, reply);
|
||||||
|
int stream = data.readInt32();
|
||||||
|
uint32_t inPastMs = (uint32_t)data.readInt32();
|
||||||
|
reply->writeInt32( isStreamActive(stream, inPastMs) );
|
||||||
|
return NO_ERROR;
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return BBinder::onTransact(code, data, reply, flags);
|
return BBinder::onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
|
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
|
||||||
// is properly propagated through your change. Not doing so will result in a loss of user
|
// is properly propagated through your change. Not doing so will result in a loss of user
|
||||||
// settings.
|
// settings.
|
||||||
private static final int DATABASE_VERSION = 63;
|
private static final int DATABASE_VERSION = 64;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@ -797,6 +797,28 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
upgradeVersion = 63;
|
upgradeVersion = 63;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upgradeVersion == 63) {
|
||||||
|
// This upgrade adds the STREAM_MUSIC type to the list of
|
||||||
|
// types affected by ringer modes (silent, vibrate, etc.)
|
||||||
|
db.beginTransaction();
|
||||||
|
try {
|
||||||
|
db.execSQL("DELETE FROM system WHERE name='"
|
||||||
|
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
|
||||||
|
int newValue = (1 << AudioManager.STREAM_RING)
|
||||||
|
| (1 << AudioManager.STREAM_NOTIFICATION)
|
||||||
|
| (1 << AudioManager.STREAM_SYSTEM)
|
||||||
|
| (1 << AudioManager.STREAM_SYSTEM_ENFORCED)
|
||||||
|
| (1 << AudioManager.STREAM_MUSIC);
|
||||||
|
db.execSQL("INSERT INTO system ('name', 'value') values ('"
|
||||||
|
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
|
||||||
|
+ String.valueOf(newValue) + "')");
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
upgradeVersion = 64;
|
||||||
|
}
|
||||||
|
|
||||||
// *** Remember to update DATABASE_VERSION above!
|
// *** Remember to update DATABASE_VERSION above!
|
||||||
|
|
||||||
if (upgradeVersion != currentVersion) {
|
if (upgradeVersion != currentVersion) {
|
||||||
@ -1057,10 +1079,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
|
|
||||||
loadVibrateSetting(db, false);
|
loadVibrateSetting(db, false);
|
||||||
|
|
||||||
// By default, only the ring/notification and system streams are affected
|
// By default, only the ring/notification, system and music streams are affected
|
||||||
loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
|
loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
|
||||||
(1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
|
(1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
|
||||||
(1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED));
|
(1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED) |
|
||||||
|
(1 << AudioManager.STREAM_MUSIC));
|
||||||
|
|
||||||
loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
|
loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
|
||||||
((1 << AudioManager.STREAM_MUSIC) |
|
((1 << AudioManager.STREAM_MUSIC) |
|
||||||
|
@ -624,17 +624,6 @@ bool AudioFlinger::streamMute(int stream) const
|
|||||||
return mStreamTypes[stream].mute;
|
return mStreamTypes[stream].mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioFlinger::isStreamActive(int stream) const
|
|
||||||
{
|
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
|
|
||||||
if (mPlaybackThreads.valueAt(i)->isStreamActive(stream)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
|
status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
|
||||||
{
|
{
|
||||||
status_t result;
|
status_t result;
|
||||||
@ -1291,20 +1280,6 @@ bool AudioFlinger::PlaybackThread::streamMute(int stream) const
|
|||||||
return mStreamTypes[stream].mute;
|
return mStreamTypes[stream].mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioFlinger::PlaybackThread::isStreamActive(int stream) const
|
|
||||||
{
|
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
size_t count = mActiveTracks.size();
|
|
||||||
for (size_t i = 0 ; i < count ; ++i) {
|
|
||||||
sp<Track> t = mActiveTracks[i].promote();
|
|
||||||
if (t == 0) continue;
|
|
||||||
Track* const track = t.get();
|
|
||||||
if (t->type() == stream)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// addTrack_l() must be called with ThreadBase::mLock held
|
// addTrack_l() must be called with ThreadBase::mLock held
|
||||||
status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
|
status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
|
||||||
{
|
{
|
||||||
|
@ -107,8 +107,6 @@ public:
|
|||||||
virtual status_t setMicMute(bool state);
|
virtual status_t setMicMute(bool state);
|
||||||
virtual bool getMicMute() const;
|
virtual bool getMicMute() const;
|
||||||
|
|
||||||
virtual bool isStreamActive(int stream) const;
|
|
||||||
|
|
||||||
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs);
|
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs);
|
||||||
virtual String8 getParameters(int ioHandle, const String8& keys);
|
virtual String8 getParameters(int ioHandle, const String8& keys);
|
||||||
|
|
||||||
@ -579,8 +577,6 @@ private:
|
|||||||
virtual float streamVolume(int stream) const;
|
virtual float streamVolume(int stream) const;
|
||||||
virtual bool streamMute(int stream) const;
|
virtual bool streamMute(int stream) const;
|
||||||
|
|
||||||
bool isStreamActive(int stream) const;
|
|
||||||
|
|
||||||
sp<Track> createTrack_l(
|
sp<Track> createTrack_l(
|
||||||
const sp<AudioFlinger::Client>& client,
|
const sp<AudioFlinger::Client>& client,
|
||||||
int streamType,
|
int streamType,
|
||||||
|
@ -312,8 +312,7 @@ void AudioPolicyManagerBase::setPhoneState(int state)
|
|||||||
|
|
||||||
// Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
|
// Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
|
||||||
if (state == AudioSystem::MODE_RINGTONE &&
|
if (state == AudioSystem::MODE_RINGTONE &&
|
||||||
(hwOutputDesc->mRefCount[AudioSystem::MUSIC] ||
|
isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
|
||||||
(systemTime() - mMusicStopTime) < seconds(SONIFICATION_HEADSET_MUSIC_DELAY))) {
|
|
||||||
mLimitRingtoneVolume = true;
|
mLimitRingtoneVolume = true;
|
||||||
} else {
|
} else {
|
||||||
mLimitRingtoneVolume = false;
|
mLimitRingtoneVolume = false;
|
||||||
@ -478,6 +477,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||||||
outputDesc->mLatency = 0;
|
outputDesc->mLatency = 0;
|
||||||
outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
|
outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
|
||||||
outputDesc->mRefCount[stream] = 0;
|
outputDesc->mRefCount[stream] = 0;
|
||||||
|
outputDesc->mStopTime[stream] = 0;
|
||||||
output = mpClientInterface->openOutput(&outputDesc->mDevice,
|
output = mpClientInterface->openOutput(&outputDesc->mDevice,
|
||||||
&outputDesc->mSamplingRate,
|
&outputDesc->mSamplingRate,
|
||||||
&outputDesc->mFormat,
|
&outputDesc->mFormat,
|
||||||
@ -606,10 +606,8 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output,
|
|||||||
if (outputDesc->mRefCount[stream] > 0) {
|
if (outputDesc->mRefCount[stream] > 0) {
|
||||||
// decrement usage count of this stream on the output
|
// decrement usage count of this stream on the output
|
||||||
outputDesc->changeRefCount(stream, -1);
|
outputDesc->changeRefCount(stream, -1);
|
||||||
// store time at which the last music track was stopped - see computeVolume()
|
// store time at which the stream was stopped - see isStreamActive()
|
||||||
if (stream == AudioSystem::MUSIC) {
|
outputDesc->mStopTime[stream] = systemTime();
|
||||||
mMusicStopTime = systemTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
setOutputDevice(output, getNewDevice(output));
|
setOutputDevice(output, getNewDevice(output));
|
||||||
|
|
||||||
@ -919,6 +917,19 @@ status_t AudioPolicyManagerBase::unregisterEffect(int id)
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const
|
||||||
|
{
|
||||||
|
nsecs_t sysTime = systemTime();
|
||||||
|
for (size_t i = 0; i < mOutputs.size(); i++) {
|
||||||
|
if (mOutputs.valueAt(i)->mRefCount[stream] != 0 ||
|
||||||
|
ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t AudioPolicyManagerBase::dump(int fd)
|
status_t AudioPolicyManagerBase::dump(int fd)
|
||||||
{
|
{
|
||||||
const size_t SIZE = 256;
|
const size_t SIZE = 256;
|
||||||
@ -1009,7 +1020,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien
|
|||||||
Thread(false),
|
Thread(false),
|
||||||
#endif //AUDIO_POLICY_TEST
|
#endif //AUDIO_POLICY_TEST
|
||||||
mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0),
|
mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0),
|
||||||
mMusicStopTime(0), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
|
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
|
||||||
mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
|
mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
|
||||||
mA2dpSuspended(false)
|
mA2dpSuspended(false)
|
||||||
{
|
{
|
||||||
@ -2036,6 +2047,7 @@ AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
|
|||||||
mRefCount[i] = 0;
|
mRefCount[i] = 0;
|
||||||
mCurVolume[i] = -1.0;
|
mCurVolume[i] = -1.0;
|
||||||
mMuteCount[i] = 0;
|
mMuteCount[i] = 0;
|
||||||
|
mStopTime[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2086,7 +2098,6 @@ uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing
|
|||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
|
status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
|
||||||
{
|
{
|
||||||
const size_t SIZE = 256;
|
const size_t SIZE = 256;
|
||||||
|
@ -394,6 +394,15 @@ status_t AudioPolicyService::unregisterEffect(int id)
|
|||||||
return mpPolicyManager->unregisterEffect(id);
|
return mpPolicyManager->unregisterEffect(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const
|
||||||
|
{
|
||||||
|
if (mpPolicyManager == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
return mpPolicyManager->isStreamActive(stream, inPastMs);
|
||||||
|
}
|
||||||
|
|
||||||
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
|
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
|
||||||
LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
|
LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
|
||||||
IPCThreadState::self()->getCallingPid());
|
IPCThreadState::self()->getCallingPid());
|
||||||
|
@ -88,6 +88,7 @@ public:
|
|||||||
int session,
|
int session,
|
||||||
int id);
|
int id);
|
||||||
virtual status_t unregisterEffect(int id);
|
virtual status_t unregisterEffect(int id);
|
||||||
|
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
|
||||||
|
|
||||||
virtual status_t onTransact(
|
virtual status_t onTransact(
|
||||||
uint32_t code,
|
uint32_t code,
|
||||||
@ -230,8 +231,8 @@ private:
|
|||||||
status_t dumpPermissionDenial(int fd);
|
status_t dumpPermissionDenial(int fd);
|
||||||
|
|
||||||
|
|
||||||
Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing device
|
mutable Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing
|
||||||
// connection stated our routing
|
// device connection state or routing
|
||||||
AudioPolicyInterface* mpPolicyManager; // the platform specific policy manager
|
AudioPolicyInterface* mpPolicyManager; // the platform specific policy manager
|
||||||
sp <AudioCommandThread> mAudioCommandThread; // audio commands thread
|
sp <AudioCommandThread> mAudioCommandThread; // audio commands thread
|
||||||
sp <AudioCommandThread> mTonePlaybackThread; // tone playback thread
|
sp <AudioCommandThread> mTonePlaybackThread; // tone playback thread
|
||||||
|
Reference in New Issue
Block a user