am bc6f59a1
: Merge "VolumeZen: Introduce internal vs external ringer mode." into lmp-mr1-dev
* commit 'bc6f59a1ef341231c2b57e0cde691be1a5a32203': VolumeZen: Introduce internal vs external ringer mode.
This commit is contained in:
@ -469,6 +469,49 @@ public class AudioManager {
|
||||
*/
|
||||
public static final int FLAG_SHOW_UI_WARNINGS = 1 << 10;
|
||||
|
||||
/**
|
||||
* Adjusting the volume down from vibrated was prevented, display a hint in the UI.
|
||||
* @hide
|
||||
*/
|
||||
public static final int FLAG_SHOW_VIBRATE_HINT = 1 << 11;
|
||||
|
||||
private static final String[] FLAG_NAMES = {
|
||||
"FLAG_SHOW_UI",
|
||||
"FLAG_ALLOW_RINGER_MODES",
|
||||
"FLAG_PLAY_SOUND",
|
||||
"FLAG_REMOVE_SOUND_AND_VIBRATE",
|
||||
"FLAG_VIBRATE",
|
||||
"FLAG_FIXED_VOLUME",
|
||||
"FLAG_BLUETOOTH_ABS_VOLUME",
|
||||
"FLAG_SHOW_SILENT_HINT",
|
||||
"FLAG_HDMI_SYSTEM_AUDIO_VOLUME",
|
||||
"FLAG_ACTIVE_MEDIA_ONLY",
|
||||
"FLAG_SHOW_UI_WARNINGS",
|
||||
"FLAG_SHOW_VIBRATE_HINT",
|
||||
};
|
||||
|
||||
/** @hide */
|
||||
public static String flagsToString(int flags) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < FLAG_NAMES.length; i++) {
|
||||
final int flag = 1 << i;
|
||||
if ((flags & flag) != 0) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(FLAG_NAMES[i]);
|
||||
flags &= ~flag;
|
||||
}
|
||||
}
|
||||
if (flags != 0) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(flags);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ringer mode that will be silent and will not vibrate. (This overrides the
|
||||
* vibrate setting.)
|
||||
@ -857,7 +900,7 @@ public class AudioManager {
|
||||
public int getRingerMode() {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
return service.getRingerMode();
|
||||
return service.getRingerModeExternal();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Dead object in getRingerMode", e);
|
||||
return RINGER_MODE_NORMAL;
|
||||
@ -977,21 +1020,12 @@ public class AudioManager {
|
||||
* @see #isVolumeFixed()
|
||||
*/
|
||||
public void setRingerMode(int ringerMode) {
|
||||
setRingerMode(ringerMode, true /*checkZen*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setRingerMode(int)
|
||||
* @param checkZen Update zen mode if necessary to compensate.
|
||||
* @hide
|
||||
*/
|
||||
public void setRingerMode(int ringerMode, boolean checkZen) {
|
||||
if (!isValidRingerMode(ringerMode)) {
|
||||
return;
|
||||
}
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
service.setRingerMode(ringerMode, checkZen);
|
||||
service.setRingerModeExternal(ringerMode, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Dead object in setRingerMode", e);
|
||||
}
|
||||
@ -3307,6 +3341,31 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for volume controllers.
|
||||
* @hide
|
||||
*/
|
||||
public void setRingerModeInternal(int ringerMode) {
|
||||
try {
|
||||
getService().setRingerModeInternal(ringerMode, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error calling setRingerModeInternal", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for volume controllers.
|
||||
* @hide
|
||||
*/
|
||||
public int getRingerModeInternal() {
|
||||
try {
|
||||
return getService().getRingerModeInternal();
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error calling getRingerModeInternal", e);
|
||||
return RINGER_MODE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Hdmi Cec system audio mode.
|
||||
*
|
||||
|
@ -38,4 +38,20 @@ public abstract class AudioManagerInternal {
|
||||
|
||||
public abstract void adjustMasterVolumeForUid(int steps, int flags, String callingPackage,
|
||||
int uid);
|
||||
|
||||
public abstract void setRingerModeDelegate(RingerModeDelegate delegate);
|
||||
|
||||
public abstract int getRingerModeInternal();
|
||||
|
||||
public abstract void setRingerModeInternal(int ringerMode, String caller);
|
||||
|
||||
public interface RingerModeDelegate {
|
||||
/** Called when external ringer mode is evaluated, returns the new internal ringer mode */
|
||||
int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
|
||||
int ringerModeInternal);
|
||||
|
||||
/** Called when internal ringer mode is evaluated, returns the new external ringer mode */
|
||||
int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
|
||||
int ringerModeExternal);
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.provider.Settings.System;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.text.TextUtils;
|
||||
@ -375,7 +374,8 @@ public class AudioService extends IAudioService.Stub {
|
||||
* {@link AudioManager#RINGER_MODE_VIBRATE}.
|
||||
*/
|
||||
// protected by mSettingsLock
|
||||
private int mRingerMode;
|
||||
private int mRingerMode; // internal ringer mode, affects muting of underlying streams
|
||||
private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager)
|
||||
|
||||
/** @see System#MODE_RINGER_STREAMS_AFFECTED */
|
||||
private int mRingerModeAffectedStreams = 0;
|
||||
@ -532,6 +532,8 @@ public class AudioService extends IAudioService.Stub {
|
||||
|
||||
private static Long mLastDeviceConnectMsgTime = new Long(0);
|
||||
|
||||
private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Construction
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -619,7 +621,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
// Call setRingerModeInt() to apply correct mute
|
||||
// state on streams affected by ringer mode.
|
||||
mRingerModeMutedStreams = 0;
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
|
||||
// Register for device connection intent broadcasts.
|
||||
IntentFilter intentFilter =
|
||||
@ -829,7 +831,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
if (updateVolumes) {
|
||||
mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias]);
|
||||
// apply stream mute states according to new value of mRingerModeAffectedStreams
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_SET_ALL_VOLUMES,
|
||||
SENDMSG_QUEUE,
|
||||
@ -883,6 +885,9 @@ public class AudioService extends IAudioService.Stub {
|
||||
}
|
||||
synchronized(mSettingsLock) {
|
||||
mRingerMode = ringerMode;
|
||||
if (mRingerModeExternal == -1) {
|
||||
mRingerModeExternal = mRingerMode;
|
||||
}
|
||||
|
||||
// System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
|
||||
// are still needed while setVibrateSetting() and getVibrateSetting() are being
|
||||
@ -1067,7 +1072,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
// or the stream type is one that is affected by ringer modes
|
||||
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
|
||||
(streamTypeAlias == getMasterStreamType())) {
|
||||
int ringerMode = getRingerMode();
|
||||
int ringerMode = getRingerModeInternal();
|
||||
// do not vibrate if already in vibrate mode
|
||||
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
flags &= ~AudioManager.FLAG_VIBRATE;
|
||||
@ -1080,6 +1085,10 @@ public class AudioService extends IAudioService.Stub {
|
||||
if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
|
||||
flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
|
||||
}
|
||||
// If suppressing a volume down adjustment in vibrate mode, display the UI hint
|
||||
if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
|
||||
flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
|
||||
}
|
||||
}
|
||||
|
||||
int oldIndex = mStreamStates[streamType].getIndex(device);
|
||||
@ -1206,7 +1215,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
} else {
|
||||
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
|
||||
}
|
||||
setRingerMode(newRingerMode, false /*checkZen*/);
|
||||
setRingerMode(newRingerMode, TAG + ".onSetStreamVolume", false /*external*/);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1769,8 +1778,15 @@ public class AudioService extends IAudioService.Stub {
|
||||
: 0, UserHandle.getCallingUserId(), null, PERSIST_DELAY);
|
||||
}
|
||||
|
||||
/** @see AudioManager#getRingerMode() */
|
||||
public int getRingerMode() {
|
||||
@Override
|
||||
public int getRingerModeExternal() {
|
||||
synchronized(mSettingsLock) {
|
||||
return mRingerModeExternal;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRingerModeInternal() {
|
||||
synchronized(mSettingsLock) {
|
||||
return mRingerMode;
|
||||
}
|
||||
@ -1787,36 +1803,57 @@ public class AudioService extends IAudioService.Stub {
|
||||
return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
|
||||
}
|
||||
|
||||
/** @see AudioManager#setRingerMode(int) */
|
||||
public void setRingerMode(int ringerMode, boolean checkZen) {
|
||||
public void setRingerModeExternal(int ringerMode, String caller) {
|
||||
setRingerMode(ringerMode, caller, true /*external*/);
|
||||
}
|
||||
|
||||
public void setRingerModeInternal(int ringerMode, String caller) {
|
||||
enforceSelfOrSystemUI("setRingerModeInternal");
|
||||
setRingerMode(ringerMode, caller, false /*external*/);
|
||||
}
|
||||
|
||||
private void setRingerMode(int ringerMode, String caller, boolean external) {
|
||||
if (mUseFixedVolume || isPlatformTelevision()) {
|
||||
return;
|
||||
}
|
||||
if (caller == null || caller.length() == 0) {
|
||||
throw new IllegalArgumentException("Bad caller: " + caller);
|
||||
}
|
||||
ensureValidRingerMode(ringerMode);
|
||||
if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
|
||||
ringerMode = AudioManager.RINGER_MODE_SILENT;
|
||||
}
|
||||
if (checkZen) {
|
||||
checkZen(ringerMode);
|
||||
}
|
||||
if (ringerMode != getRingerMode()) {
|
||||
setRingerModeInt(ringerMode, true);
|
||||
// Send sticky broadcast
|
||||
broadcastRingerMode(ringerMode);
|
||||
final int ringerModeInternal = getRingerModeInternal();
|
||||
final int ringerModeExternal = getRingerModeExternal();
|
||||
if (external) {
|
||||
setRingerModeExt(ringerMode);
|
||||
if (mRingerModeDelegate != null) {
|
||||
ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
|
||||
ringerMode, caller, ringerModeInternal);
|
||||
}
|
||||
if (ringerMode != ringerModeInternal) {
|
||||
setRingerModeInt(ringerMode, true /*persist*/);
|
||||
}
|
||||
} else /*internal*/ {
|
||||
if (ringerMode != ringerModeInternal) {
|
||||
setRingerModeInt(ringerMode, true /*persist*/);
|
||||
mVolumeController.postInternalRingerModeChanged(ringerMode);
|
||||
}
|
||||
if (mRingerModeDelegate != null) {
|
||||
ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
|
||||
ringerMode, caller, ringerModeExternal);
|
||||
}
|
||||
setRingerModeExt(ringerMode);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkZen(int ringerMode) {
|
||||
// leave zen when callers set ringer-mode = normal or vibrate
|
||||
final int zen = Global.getInt(mContentResolver, Global.ZEN_MODE, Global.ZEN_MODE_OFF);
|
||||
if (ringerMode != AudioManager.RINGER_MODE_SILENT && zen != Global.ZEN_MODE_OFF) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Global.putInt(mContentResolver, Global.ZEN_MODE, Global.ZEN_MODE_OFF);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
private void setRingerModeExt(int ringerMode) {
|
||||
synchronized(mSettingsLock) {
|
||||
if (ringerMode == mRingerModeExternal) return;
|
||||
mRingerModeExternal = ringerMode;
|
||||
}
|
||||
// Send sticky broadcast
|
||||
broadcastRingerMode(ringerMode);
|
||||
}
|
||||
|
||||
private void setRingerModeInt(int ringerMode, boolean persist) {
|
||||
@ -1829,34 +1866,35 @@ public class AudioService extends IAudioService.Stub {
|
||||
// Unmute stream if previously muted by ringer mode and ringer mode
|
||||
// is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
|
||||
int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||
final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
|
||||
|| ringerMode == AudioManager.RINGER_MODE_SILENT;
|
||||
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
||||
if (isStreamMutedByRingerMode(streamType)) {
|
||||
if (!isStreamAffectedByRingerMode(streamType) ||
|
||||
ringerMode == AudioManager.RINGER_MODE_NORMAL) {
|
||||
// ring and notifications volume should never be 0 when not silenced
|
||||
// on voice capable devices or devices that support vibration
|
||||
if ((isPlatformVoice() || mHasVibrator) &&
|
||||
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
Set set = mStreamStates[streamType].mIndex.entrySet();
|
||||
Iterator i = set.iterator();
|
||||
while (i.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)i.next();
|
||||
if ((Integer)entry.getValue() == 0) {
|
||||
entry.setValue(10);
|
||||
}
|
||||
final boolean isMuted = isStreamMutedByRingerMode(streamType);
|
||||
final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType);
|
||||
if (isMuted == shouldMute) continue;
|
||||
if (!shouldMute) {
|
||||
// unmute
|
||||
// ring and notifications volume should never be 0 when not silenced
|
||||
// on voice capable devices or devices that support vibration
|
||||
if ((isPlatformVoice() || mHasVibrator) &&
|
||||
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
Set set = mStreamStates[streamType].mIndex.entrySet();
|
||||
Iterator i = set.iterator();
|
||||
while (i.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)i.next();
|
||||
if ((Integer)entry.getValue() == 0) {
|
||||
entry.setValue(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
mStreamStates[streamType].mute(null, false);
|
||||
mRingerModeMutedStreams &= ~(1 << streamType);
|
||||
}
|
||||
mStreamStates[streamType].mute(null, false);
|
||||
mRingerModeMutedStreams &= ~(1 << streamType);
|
||||
} else {
|
||||
if (isStreamAffectedByRingerMode(streamType) &&
|
||||
ringerMode != AudioManager.RINGER_MODE_NORMAL) {
|
||||
mStreamStates[streamType].mute(null, true);
|
||||
mRingerModeMutedStreams |= (1 << streamType);
|
||||
}
|
||||
// mute
|
||||
mStreamStates[streamType].mute(null, true);
|
||||
mRingerModeMutedStreams |= (1 << streamType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1888,10 +1926,10 @@ public class AudioService extends IAudioService.Stub {
|
||||
switch (getVibrateSetting(vibrateType)) {
|
||||
|
||||
case AudioManager.VIBRATE_SETTING_ON:
|
||||
return getRingerMode() != AudioManager.RINGER_MODE_SILENT;
|
||||
return getRingerModeInternal() != AudioManager.RINGER_MODE_SILENT;
|
||||
|
||||
case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
|
||||
return getRingerMode() == AudioManager.RINGER_MODE_VIBRATE;
|
||||
return getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE;
|
||||
|
||||
case AudioManager.VIBRATE_SETTING_OFF:
|
||||
// return false, even for incoming calls
|
||||
@ -2352,7 +2390,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
|
||||
// apply new ringer mode before checking volume for alias streams so that streams
|
||||
// muted by ringer mode have the correct volume
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
|
||||
checkAllFixedVolumeDevices();
|
||||
checkAllAliasStreamVolumes();
|
||||
@ -3003,7 +3041,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
*/
|
||||
private int checkForRingerModeChange(int oldIndex, int direction, int step) {
|
||||
int result = FLAG_ADJUST_VOLUME;
|
||||
int ringerMode = getRingerMode();
|
||||
int ringerMode = getRingerModeInternal();
|
||||
|
||||
switch (ringerMode) {
|
||||
case RINGER_MODE_NORMAL:
|
||||
@ -3037,6 +3075,8 @@ public class AudioService extends IAudioService.Stub {
|
||||
if (VOLUME_SETS_RINGER_MODE_SILENT
|
||||
&& mPrevVolDirection != AudioManager.ADJUST_LOWER) {
|
||||
ringerMode = RINGER_MODE_SILENT;
|
||||
} else {
|
||||
result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
|
||||
}
|
||||
} else if (direction == AudioManager.ADJUST_RAISE) {
|
||||
ringerMode = RINGER_MODE_NORMAL;
|
||||
@ -3062,7 +3102,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
break;
|
||||
}
|
||||
|
||||
setRingerMode(ringerMode, false /*checkZen*/);
|
||||
setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
|
||||
|
||||
mPrevVolDirection = direction;
|
||||
|
||||
@ -4136,7 +4176,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
case MSG_PERSIST_RINGER_MODE:
|
||||
// note that the value persisted is the current ringer mode, not the
|
||||
// value of ringer mode as of the time the request was made to persist
|
||||
persistRingerMode(getRingerMode());
|
||||
persistRingerMode(getRingerModeInternal());
|
||||
break;
|
||||
|
||||
case MSG_MEDIA_SERVER_DIED:
|
||||
@ -4188,7 +4228,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
}
|
||||
|
||||
// Restore ringer mode
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
|
||||
// Restore master volume
|
||||
restoreMasterVolume();
|
||||
@ -4358,7 +4398,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
* Ensure all stream types that should be affected by ringer mode
|
||||
* are in the proper state.
|
||||
*/
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
}
|
||||
readDockAudioSettings(mContentResolver);
|
||||
}
|
||||
@ -5110,7 +5150,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
|
||||
}
|
||||
// take new state into account for streams muted by ringer mode
|
||||
setRingerModeInt(getRingerMode(), false);
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
}
|
||||
|
||||
sendMsg(mAudioHandler,
|
||||
@ -5451,11 +5491,13 @@ public class AudioService extends IAudioService.Stub {
|
||||
|
||||
private void dumpRingerMode(PrintWriter pw) {
|
||||
pw.println("\nRinger mode: ");
|
||||
pw.println("- mode: "+RINGER_MODE_NAMES[mRingerMode]);
|
||||
pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
|
||||
pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
|
||||
pw.print("- ringer mode affected streams = 0x");
|
||||
pw.println(Integer.toHexString(mRingerModeAffectedStreams));
|
||||
pw.print("- ringer mode muted streams = 0x");
|
||||
pw.println(Integer.toHexString(mRingerModeMutedStreams));
|
||||
pw.print("- delegate = "); pw.println(mRingerModeDelegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -5477,6 +5519,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
|
||||
pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs);
|
||||
pw.print(" mMcc="); pw.println(mMcc);
|
||||
pw.print(" mHasVibrator="); pw.println(mHasVibrator);
|
||||
}
|
||||
|
||||
private static String safeMediaVolumeStateToString(Integer state) {
|
||||
@ -5668,6 +5711,16 @@ public class AudioService extends IAudioService.Stub {
|
||||
Log.w(TAG, "Error calling dismiss", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void postInternalRingerModeChanged(int mode) {
|
||||
if (mController == null)
|
||||
return;
|
||||
try {
|
||||
mController.internalRingerModeChanged(mode);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error calling internalRingerModeChanged", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5675,6 +5728,13 @@ public class AudioService extends IAudioService.Stub {
|
||||
* LocalServices.
|
||||
*/
|
||||
final class AudioServiceInternal extends AudioManagerInternal {
|
||||
@Override
|
||||
public void setRingerModeDelegate(RingerModeDelegate delegate) {
|
||||
mRingerModeDelegate = delegate;
|
||||
if (mRingerModeDelegate != null) {
|
||||
setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
|
||||
@ -5701,6 +5761,16 @@ public class AudioService extends IAudioService.Stub {
|
||||
int uid) {
|
||||
adjustMasterVolume(steps, flags, callingPackage, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRingerModeInternal() {
|
||||
return AudioService.this.getRingerModeInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRingerModeInternal(int ringerMode, String caller) {
|
||||
AudioService.this.setRingerModeInternal(ringerMode, caller);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================================
|
||||
|
@ -77,9 +77,13 @@ interface IAudioService {
|
||||
|
||||
void setMicrophoneMute(boolean on, String callingPackage);
|
||||
|
||||
void setRingerMode(int ringerMode, boolean checkZen);
|
||||
void setRingerModeExternal(int ringerMode, String caller);
|
||||
|
||||
int getRingerMode();
|
||||
void setRingerModeInternal(int ringerMode, String caller);
|
||||
|
||||
int getRingerModeExternal();
|
||||
|
||||
int getRingerModeInternal();
|
||||
|
||||
boolean isValidRingerMode(int ringerMode);
|
||||
|
||||
|
@ -34,4 +34,6 @@ oneway interface IVolumeController {
|
||||
void setLayoutDirection(int layoutDirection);
|
||||
|
||||
void dismiss();
|
||||
|
||||
void internalRingerModeChanged(int mode);
|
||||
}
|
||||
|
@ -1028,6 +1028,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
}
|
||||
|
||||
public void onInternalRingerModeChanged() {
|
||||
if (mIconPolicy != null) {
|
||||
mIconPolicy.updateVolumeZen();
|
||||
}
|
||||
}
|
||||
|
||||
private void startKeyguard() {
|
||||
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
|
||||
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
|
||||
|
@ -208,7 +208,7 @@ public class PhoneStatusBarPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private final void updateVolumeZen() {
|
||||
public final void updateVolumeZen() {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
boolean zenVisible = false;
|
||||
@ -230,7 +230,7 @@ public class PhoneStatusBarPolicy {
|
||||
}
|
||||
|
||||
if (mZen != Global.ZEN_MODE_NO_INTERRUPTIONS &&
|
||||
audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
volumeVisible = true;
|
||||
volumeIconId = R.drawable.stat_sys_ringer_vibrate;
|
||||
volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
|
||||
|
@ -157,8 +157,9 @@ public class ZenModeControllerImpl implements ZenModeController {
|
||||
if (mRegistered) {
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
mContext.registerReceiverAsUser(mReceiver, new UserHandle(mUserId),
|
||||
new IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED), null, null);
|
||||
final IntentFilter filter = new IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
|
||||
filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
|
||||
mContext.registerReceiverAsUser(mReceiver, new UserHandle(mUserId), filter, null, null);
|
||||
mRegistered = true;
|
||||
mSetupObserver.register();
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
public class IconPulser {
|
||||
private static final float PULSE_SCALE = 1.1f;
|
||||
|
||||
private final Interpolator mFastOutSlowInInterpolator;
|
||||
|
||||
public IconPulser(Context context) {
|
||||
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
|
||||
android.R.interpolator.fast_out_slow_in);
|
||||
}
|
||||
|
||||
public void start(final View target) {
|
||||
if (target == null || target.getScaleX() != 1) return; // n/a, or already running
|
||||
target.animate().cancel();
|
||||
target.animate().scaleX(PULSE_SCALE).scaleY(PULSE_SCALE)
|
||||
.setInterpolator(mFastOutSlowInInterpolator)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
target.animate().scaleX(1).scaleY(1).setListener(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -124,6 +124,8 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
private static final int MSG_ZEN_MODE_AVAILABLE_CHANGED = 13;
|
||||
private static final int MSG_USER_ACTIVITY = 14;
|
||||
private static final int MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED = 15;
|
||||
private static final int MSG_ZEN_MODE_CHANGED = 16;
|
||||
private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 17;
|
||||
|
||||
// Pseudo stream type for master volume
|
||||
private static final int STREAM_MASTER = -100;
|
||||
@ -169,6 +171,8 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
private final ViewGroup mSliderPanel;
|
||||
/** The zen mode configuration panel view */
|
||||
private ZenModePanel mZenPanel;
|
||||
/** The component currently suppressing notification stream effects */
|
||||
private ComponentName mNotificationEffectsSuppressor;
|
||||
|
||||
private Callback mCallback;
|
||||
|
||||
@ -178,6 +182,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
private SparseArray<StreamControl> mStreamControls;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final SecondaryIconTransition mSecondaryIconTransition;
|
||||
private final IconPulser mIconPulser;
|
||||
|
||||
private enum StreamResources {
|
||||
BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
|
||||
@ -188,7 +193,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
RingerStream(AudioManager.STREAM_RING,
|
||||
R.string.volume_icon_description_ringer,
|
||||
com.android.systemui.R.drawable.ic_ringer_audible,
|
||||
com.android.systemui.R.drawable.ic_ringer_vibrate,
|
||||
com.android.systemui.R.drawable.ic_ringer_mute,
|
||||
false),
|
||||
VoiceStream(AudioManager.STREAM_VOICE_CALL,
|
||||
R.string.volume_icon_description_incall,
|
||||
@ -208,7 +213,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
NotificationStream(AudioManager.STREAM_NOTIFICATION,
|
||||
R.string.volume_icon_description_notification,
|
||||
com.android.systemui.R.drawable.ic_ringer_audible,
|
||||
com.android.systemui.R.drawable.ic_ringer_vibrate,
|
||||
com.android.systemui.R.drawable.ic_ringer_mute,
|
||||
true),
|
||||
// for now, use media resources for master volume
|
||||
MasterStream(STREAM_MASTER,
|
||||
@ -268,6 +273,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
// Synchronize when accessing this
|
||||
private ToneGenerator mToneGenerators[];
|
||||
private Vibrator mVibrator;
|
||||
private boolean mHasVibrator;
|
||||
|
||||
private static AlertDialog sSafetyWarning;
|
||||
private static Object sSafetyWarningLock = new Object();
|
||||
@ -354,6 +360,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
|
||||
Context.ACCESSIBILITY_SERVICE);
|
||||
mSecondaryIconTransition = new SecondaryIconTransition();
|
||||
mIconPulser = new IconPulser(context);
|
||||
|
||||
// For now, only show master volume if master volume is supported
|
||||
final Resources res = context.getResources();
|
||||
@ -435,10 +442,12 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
|
||||
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
|
||||
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
|
||||
mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
|
||||
|
||||
if (mZenController != null && !useMasterVolume) {
|
||||
mZenModeAvailable = mZenController.isZenAvailable();
|
||||
mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
|
||||
mZenController.addCallback(mZenCallback);
|
||||
}
|
||||
|
||||
@ -470,8 +479,10 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
pw.print(" mTag="); pw.println(mTag);
|
||||
pw.print(" mRingIsSilent="); pw.println(mRingIsSilent);
|
||||
pw.print(" mVoiceCapable="); pw.println(mVoiceCapable);
|
||||
pw.print(" mHasVibrator="); pw.println(mHasVibrator);
|
||||
pw.print(" mZenModeAvailable="); pw.println(mZenModeAvailable);
|
||||
pw.print(" mZenPanelExpanded="); pw.println(mZenPanelExpanded);
|
||||
pw.print(" mNotificationEffectsSuppressor="); pw.println(mNotificationEffectsSuppressor);
|
||||
pw.print(" mTimeoutDelay="); pw.println(mTimeoutDelay);
|
||||
pw.print(" mDisabledAlpha="); pw.println(mDisabledAlpha);
|
||||
pw.print(" mLastRingerMode="); pw.println(mLastRingerMode);
|
||||
@ -639,16 +650,19 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
sc.iconRes = streamRes.iconRes;
|
||||
sc.iconMuteRes = streamRes.iconMuteRes;
|
||||
sc.icon.setImageResource(sc.iconRes);
|
||||
sc.icon.setClickable(isNotification);
|
||||
sc.icon.setClickable(isNotification && mHasVibrator);
|
||||
if (isNotification) {
|
||||
sc.icon.setSoundEffectsEnabled(false);
|
||||
sc.icon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resetTimeout();
|
||||
toggle(sc);
|
||||
}
|
||||
});
|
||||
if (mHasVibrator) {
|
||||
sc.icon.setSoundEffectsEnabled(false);
|
||||
sc.iconMuteRes = com.android.systemui.R.drawable.ic_ringer_vibrate;
|
||||
sc.icon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resetTimeout();
|
||||
toggleRinger(sc);
|
||||
}
|
||||
});
|
||||
}
|
||||
sc.iconSuppressedRes = com.android.systemui.R.drawable.ic_ringer_mute;
|
||||
}
|
||||
sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar);
|
||||
@ -681,12 +695,13 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
}
|
||||
}
|
||||
|
||||
private void toggle(StreamControl sc) {
|
||||
if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
|
||||
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
private void toggleRinger(StreamControl sc) {
|
||||
if (!mHasVibrator) return;
|
||||
if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL) {
|
||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
|
||||
postVolumeChanged(sc.streamType, AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
|
||||
} else {
|
||||
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
|
||||
postVolumeChanged(sc.streamType, AudioManager.FLAG_PLAY_SOUND);
|
||||
}
|
||||
}
|
||||
@ -710,7 +725,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
|
||||
private void updateSliderProgress(StreamControl sc, int progress) {
|
||||
final boolean isRinger = isNotificationOrRing(sc.streamType);
|
||||
if (isRinger && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
|
||||
if (isRinger && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
|
||||
progress = mLastRingerProgress;
|
||||
}
|
||||
if (progress < 0) {
|
||||
@ -723,21 +738,30 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
}
|
||||
|
||||
private void updateSliderIcon(StreamControl sc, boolean muted) {
|
||||
ComponentName suppressor = null;
|
||||
if (isNotificationOrRing(sc.streamType)) {
|
||||
int ringerMode = mAudioManager.getRingerMode();
|
||||
suppressor = mNotificationEffectsSuppressor;
|
||||
int ringerMode = mAudioManager.getRingerModeInternal();
|
||||
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
ringerMode = mLastRingerMode;
|
||||
} else {
|
||||
mLastRingerMode = ringerMode;
|
||||
}
|
||||
muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
|
||||
if (mHasVibrator) {
|
||||
muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
|
||||
} else {
|
||||
muted = false;
|
||||
}
|
||||
}
|
||||
sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon : muted ? sc.iconMuteRes : sc.iconRes);
|
||||
sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon
|
||||
: suppressor != null ? sc.iconSuppressedRes
|
||||
: muted ? sc.iconMuteRes
|
||||
: sc.iconRes);
|
||||
}
|
||||
|
||||
private void updateSliderSupressor(StreamControl sc) {
|
||||
private void updateSliderSuppressor(StreamControl sc) {
|
||||
final ComponentName suppressor = isNotificationOrRing(sc.streamType)
|
||||
? mZenController.getEffectsSuppressor() : null;
|
||||
? mNotificationEffectsSuppressor : null;
|
||||
if (suppressor == null) {
|
||||
sc.seekbarView.setVisibility(View.VISIBLE);
|
||||
sc.suppressorView.setVisibility(View.GONE);
|
||||
@ -746,7 +770,6 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
sc.suppressorView.setVisibility(View.VISIBLE);
|
||||
sc.suppressorView.setText(mContext.getString(R.string.muted_by,
|
||||
getSuppressorCaption(suppressor)));
|
||||
sc.icon.setImageResource(sc.iconSuppressedRes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -777,7 +800,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
sc.icon.setImageDrawable(null);
|
||||
updateSliderIcon(sc, muted);
|
||||
updateSliderEnabled(sc, muted, false);
|
||||
updateSliderSupressor(sc);
|
||||
updateSliderSuppressor(sc);
|
||||
}
|
||||
|
||||
private void updateSliderEnabled(final StreamControl sc, boolean muted, boolean fixedVolume) {
|
||||
@ -787,7 +810,12 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
// never disable touch interactions for remote playback, the muting is not tied to
|
||||
// the state of the phone.
|
||||
sc.seekbarView.setEnabled(!fixedVolume);
|
||||
} else if (isRinger && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
|
||||
} else if (isRinger && mNotificationEffectsSuppressor != null) {
|
||||
sc.icon.setEnabled(true);
|
||||
sc.icon.setAlpha(1f);
|
||||
sc.icon.setClickable(false);
|
||||
} else if (isRinger
|
||||
&& mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
|
||||
sc.seekbarView.setEnabled(false);
|
||||
sc.icon.setEnabled(false);
|
||||
sc.icon.setAlpha(mDisabledAlpha);
|
||||
@ -805,7 +833,7 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
if (isRinger && wasEnabled != sc.seekbarView.isEnabled()) {
|
||||
if (sc.seekbarView.isEnabled()) {
|
||||
sc.group.setOnTouchListener(null);
|
||||
sc.icon.setClickable(true);
|
||||
sc.icon.setClickable(mHasVibrator);
|
||||
} else {
|
||||
final View.OnTouchListener showHintOnTouch = new View.OnTouchListener() {
|
||||
@Override
|
||||
@ -826,6 +854,16 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
}
|
||||
}
|
||||
|
||||
private void showVibrateHint() {
|
||||
final StreamControl active = mStreamControls.get(mActiveStreamType);
|
||||
if (active != null) {
|
||||
mIconPulser.start(active.icon);
|
||||
if (!hasMessages(MSG_VIBRATE)) {
|
||||
sendEmptyMessageDelayed(MSG_VIBRATE, VIBRATE_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNotificationOrRing(int streamType) {
|
||||
return streamType == AudioManager.STREAM_RING
|
||||
|| streamType == AudioManager.STREAM_NOTIFICATION;
|
||||
@ -953,6 +991,19 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection, 0).sendToTarget();
|
||||
}
|
||||
|
||||
public void postInternalRingerModeChanged(int mode) {
|
||||
removeMessages(MSG_INTERNAL_RINGER_MODE_CHANGED);
|
||||
obtainMessage(MSG_INTERNAL_RINGER_MODE_CHANGED, mode, 0).sendToTarget();
|
||||
}
|
||||
|
||||
private static String flagsToString(int flags) {
|
||||
return flags == 0 ? "0" : (flags + "=" + AudioManager.flagsToString(flags));
|
||||
}
|
||||
|
||||
private static String streamToString(int stream) {
|
||||
return AudioService.streamToString(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this if you have other work to do when the volume changes (for
|
||||
* example, vibrating, playing a sound, etc.). Make sure to call through to
|
||||
@ -960,7 +1011,8 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
*/
|
||||
protected void onVolumeChanged(int streamType, int flags) {
|
||||
|
||||
if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
|
||||
if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamToString(streamType)
|
||||
+ ", flags: " + flagsToString(flags) + ")");
|
||||
|
||||
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
|
||||
synchronized (this) {
|
||||
@ -989,7 +1041,8 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
|
||||
protected void onMuteChanged(int streamType, int flags) {
|
||||
|
||||
if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamType + ", flags: " + flags + ")");
|
||||
if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamToString(streamType)
|
||||
+ ", flags: " + flagsToString(flags) + ")");
|
||||
|
||||
StreamControl sc = mStreamControls.get(streamType);
|
||||
if (sc != null) {
|
||||
@ -1005,8 +1058,8 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
mRingIsSilent = false;
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(mTag, "onShowVolumeChanged(streamType: " + streamType
|
||||
+ ", flags: " + flags + "), index: " + index);
|
||||
Log.d(mTag, "onShowVolumeChanged(streamType: " + streamToString(streamType)
|
||||
+ ", flags: " + flagsToString(flags) + "), index: " + index);
|
||||
}
|
||||
|
||||
// get max volume for progress bar
|
||||
@ -1017,7 +1070,6 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
switch (streamType) {
|
||||
|
||||
case AudioManager.STREAM_RING: {
|
||||
// setRingerIcon();
|
||||
Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
|
||||
mContext, RingtoneManager.TYPE_RINGTONE);
|
||||
if (ringuri == null) {
|
||||
@ -1110,13 +1162,16 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
sc.seekbarView.setMax(max);
|
||||
}
|
||||
updateSliderProgress(sc, index);
|
||||
updateSliderEnabled(sc, isMuted(streamType),
|
||||
(flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
|
||||
// check for secondary-icon transition completion
|
||||
if (isNotificationOrRing(streamType) && mSecondaryIconTransition.isRunning()) {
|
||||
mSecondaryIconTransition.cancel(); // safe to reset
|
||||
sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
|
||||
mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
|
||||
final boolean muted = isMuted(streamType);
|
||||
updateSliderEnabled(sc, muted, (flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
|
||||
if (isNotificationOrRing(streamType)) {
|
||||
// check for secondary-icon transition completion
|
||||
if (mSecondaryIconTransition.isRunning()) {
|
||||
mSecondaryIconTransition.cancel(); // safe to reset
|
||||
sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
|
||||
mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
|
||||
}
|
||||
updateSliderIcon(sc, muted);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,15 +1189,20 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
// Do a little vibrate if applicable (only when going into vibrate mode)
|
||||
if ((streamType != STREAM_REMOTE_MUSIC) &&
|
||||
((flags & AudioManager.FLAG_VIBRATE) != 0) &&
|
||||
mAudioManager.isStreamAffectedByRingerMode(streamType) &&
|
||||
mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
isNotificationOrRing(streamType) &&
|
||||
mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
sendMessageDelayed(obtainMessage(MSG_VIBRATE), VIBRATE_DELAY);
|
||||
}
|
||||
|
||||
// Pulse the slider icon if an adjustment was suppressed due to silent mode.
|
||||
// Pulse the zen icon if an adjustment was suppressed due to silent mode.
|
||||
if ((flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
|
||||
showSilentHint();
|
||||
}
|
||||
|
||||
// Pulse the slider icon & vibrate if an adjustment down was suppressed due to vibrate mode.
|
||||
if ((flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
|
||||
showVibrateHint();
|
||||
}
|
||||
}
|
||||
|
||||
private void announceDialogShown() {
|
||||
@ -1186,16 +1246,17 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
protected void onVibrate() {
|
||||
|
||||
// Make sure we ended up in vibrate ringer mode
|
||||
if (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_VIBRATE) {
|
||||
if (mAudioManager.getRingerModeInternal() != AudioManager.RINGER_MODE_VIBRATE) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES);
|
||||
if (mVibrator != null) {
|
||||
mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onRemoteVolumeChanged(MediaController controller, int flags) {
|
||||
if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(controller:" + controller + ", flags: " + flags
|
||||
+ ")");
|
||||
if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(controller:" + controller + ", flags: "
|
||||
+ flagsToString(flags) + ")");
|
||||
|
||||
if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) {
|
||||
synchronized (this) {
|
||||
@ -1385,7 +1446,9 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ZEN_MODE_CHANGED:
|
||||
case MSG_RINGER_MODE_CHANGED:
|
||||
case MSG_INTERNAL_RINGER_MODE_CHANGED:
|
||||
case MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED: {
|
||||
if (isShowing()) {
|
||||
updateStates();
|
||||
@ -1491,10 +1554,15 @@ public class VolumePanel extends Handler implements DemoMode {
|
||||
public void onZenAvailableChanged(boolean available) {
|
||||
obtainMessage(MSG_ZEN_MODE_AVAILABLE_CHANGED, available ? 1 : 0, 0).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEffectsSupressorChanged() {
|
||||
obtainMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED,
|
||||
mZenController.getEffectsSuppressor()).sendToTarget();
|
||||
mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
|
||||
sendEmptyMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED);
|
||||
}
|
||||
|
||||
public void onZenChanged(int zen) {
|
||||
sendEmptyMessage(MSG_ZEN_MODE_CHANGED);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -181,6 +181,15 @@ public class VolumeUI extends SystemUI {
|
||||
dismissNow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalRingerModeChanged(int mode) throws RemoteException {
|
||||
mPanel.postInternalRingerModeChanged(mode);
|
||||
final PhoneStatusBar psb = getComponent(PhoneStatusBar.class);
|
||||
if (psb != null) {
|
||||
psb.onInternalRingerModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZenModeController getZenController() {
|
||||
return mPanel.getZenController();
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -38,8 +36,6 @@ import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.ImageView;
|
||||
@ -69,7 +65,6 @@ public class ZenModePanel extends LinearLayout {
|
||||
private static final int FOREVER_CONDITION_INDEX = 0;
|
||||
private static final int TIME_CONDITION_INDEX = 1;
|
||||
private static final int FIRST_CONDITION_INDEX = 2;
|
||||
private static final float SILENT_HINT_PULSE_SCALE = 1.1f;
|
||||
private static final long SELECT_DEFAULT_DELAY = 300;
|
||||
|
||||
public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
|
||||
@ -78,7 +73,7 @@ public class ZenModePanel extends LinearLayout {
|
||||
private final LayoutInflater mInflater;
|
||||
private final H mHandler = new H();
|
||||
private final Prefs mPrefs;
|
||||
private final Interpolator mFastOutSlowInInterpolator;
|
||||
private final IconPulser mIconPulser;
|
||||
private final int mSubheadWarningColor;
|
||||
private final int mSubheadColor;
|
||||
|
||||
@ -110,8 +105,7 @@ public class ZenModePanel extends LinearLayout {
|
||||
mContext = context;
|
||||
mPrefs = new Prefs();
|
||||
mInflater = LayoutInflater.from(mContext.getApplicationContext());
|
||||
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
|
||||
android.R.interpolator.fast_out_slow_in);
|
||||
mIconPulser = new IconPulser(mContext);
|
||||
final Resources res = mContext.getResources();
|
||||
mSubheadWarningColor = res.getColor(R.color.system_warning_color);
|
||||
mSubheadColor = res.getColor(R.color.qs_subhead);
|
||||
@ -283,16 +277,7 @@ public class ZenModePanel extends LinearLayout {
|
||||
if (DEBUG) Log.d(mTag, "showSilentHint");
|
||||
if (mZenButtons == null || mZenButtons.getChildCount() == 0) return;
|
||||
final View noneButton = mZenButtons.getChildAt(0);
|
||||
if (noneButton.getScaleX() != 1) return; // already running
|
||||
noneButton.animate().cancel();
|
||||
noneButton.animate().scaleX(SILENT_HINT_PULSE_SCALE).scaleY(SILENT_HINT_PULSE_SCALE)
|
||||
.setInterpolator(mFastOutSlowInInterpolator)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
noneButton.animate().scaleX(1).scaleY(1).setListener(null);
|
||||
}
|
||||
});
|
||||
mIconPulser.start(noneButton);
|
||||
}
|
||||
|
||||
private void handleUpdateZen(int zen) {
|
||||
|
@ -847,7 +847,7 @@ public class NotificationManagerService extends SystemService {
|
||||
mRankingHelper = new RankingHelper(getContext(),
|
||||
new RankingWorkerHandler(mRankingThread.getLooper()),
|
||||
extractorNames);
|
||||
mZenModeHelper = new ZenModeHelper(getContext(), mHandler);
|
||||
mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper());
|
||||
mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
|
||||
@Override
|
||||
public void onConfigChanged() {
|
||||
@ -970,7 +970,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
// Grab our optional AudioService
|
||||
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
mZenModeHelper.setAudioManager(mAudioManager);
|
||||
mZenModeHelper.onSystemReady();
|
||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||
// This observer will force an update when observe is called, causing us to
|
||||
// bind to listener services.
|
||||
@ -1412,8 +1412,8 @@ public class NotificationManagerService extends SystemService {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mNotificationList) {
|
||||
mListeners.checkServiceTokenLocked(token);
|
||||
mZenModeHelper.requestFromListener(interruptionFilter);
|
||||
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
|
||||
mZenModeHelper.requestFromListener(info.component, interruptionFilter);
|
||||
updateInterruptionFilterLocked();
|
||||
}
|
||||
} finally {
|
||||
@ -1965,7 +1965,7 @@ public class NotificationManagerService extends SystemService {
|
||||
final boolean convertSoundToVibration =
|
||||
!hasCustomVibrate
|
||||
&& hasValidSound
|
||||
&& (mAudioManager.getRingerMode()
|
||||
&& (mAudioManager.getRingerModeInternal()
|
||||
== AudioManager.RINGER_MODE_VIBRATE);
|
||||
|
||||
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
|
||||
@ -1973,7 +1973,7 @@ public class NotificationManagerService extends SystemService {
|
||||
(notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
|
||||
|
||||
if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
|
||||
&& !(mAudioManager.getRingerMode()
|
||||
&& !(mAudioManager.getRingerModeInternal()
|
||||
== AudioManager.RINGER_MODE_SILENT)) {
|
||||
mVibrateNotification = record;
|
||||
|
||||
|
@ -46,15 +46,15 @@ public class ZenLog {
|
||||
|
||||
private static final int TYPE_INTERCEPTED = 1;
|
||||
private static final int TYPE_ALLOW_DISABLE = 2;
|
||||
private static final int TYPE_SET_RINGER_MODE = 3;
|
||||
private static final int TYPE_DOWNTIME = 4;
|
||||
private static final int TYPE_SET_ZEN_MODE = 5;
|
||||
private static final int TYPE_UPDATE_ZEN_MODE = 6;
|
||||
private static final int TYPE_EXIT_CONDITION = 7;
|
||||
private static final int TYPE_SUBSCRIBE = 8;
|
||||
private static final int TYPE_UNSUBSCRIBE = 9;
|
||||
private static final int TYPE_CONFIG = 10;
|
||||
private static final int TYPE_FOLLOW_RINGER_MODE = 11;
|
||||
private static final int TYPE_SET_RINGER_MODE_EXTERNAL = 3;
|
||||
private static final int TYPE_SET_RINGER_MODE_INTERNAL = 4;
|
||||
private static final int TYPE_DOWNTIME = 5;
|
||||
private static final int TYPE_SET_ZEN_MODE = 6;
|
||||
private static final int TYPE_UPDATE_ZEN_MODE = 7;
|
||||
private static final int TYPE_EXIT_CONDITION = 8;
|
||||
private static final int TYPE_SUBSCRIBE = 9;
|
||||
private static final int TYPE_UNSUBSCRIBE = 10;
|
||||
private static final int TYPE_CONFIG = 11;
|
||||
private static final int TYPE_NOT_INTERCEPTED = 12;
|
||||
private static final int TYPE_DISABLE_EFFECTS = 13;
|
||||
|
||||
@ -71,8 +71,22 @@ public class ZenLog {
|
||||
append(TYPE_NOT_INTERCEPTED, record.getKey() + "," + reason);
|
||||
}
|
||||
|
||||
public static void traceSetRingerMode(int ringerMode) {
|
||||
append(TYPE_SET_RINGER_MODE, ringerModeToString(ringerMode));
|
||||
public static void traceSetRingerModeExternal(int ringerModeOld, int ringerModeNew,
|
||||
String caller, int ringerModeInternalIn, int ringerModeInternalOut) {
|
||||
append(TYPE_SET_RINGER_MODE_EXTERNAL, caller + ",e:" +
|
||||
ringerModeToString(ringerModeOld) + "->" +
|
||||
ringerModeToString(ringerModeNew) + ",i:" +
|
||||
ringerModeToString(ringerModeInternalIn) + "->" +
|
||||
ringerModeToString(ringerModeInternalOut));
|
||||
}
|
||||
|
||||
public static void traceSetRingerModeInternal(int ringerModeOld, int ringerModeNew,
|
||||
String caller, int ringerModeExternalIn, int ringerModeExternalOut) {
|
||||
append(TYPE_SET_RINGER_MODE_INTERNAL, caller + ",i:" +
|
||||
ringerModeToString(ringerModeOld) + "->" +
|
||||
ringerModeToString(ringerModeNew) + ",e:" +
|
||||
ringerModeToString(ringerModeExternalIn) + "->" +
|
||||
ringerModeToString(ringerModeExternalOut));
|
||||
}
|
||||
|
||||
public static void traceDowntime(int downtimeMode, int day, ArraySet<Integer> days) {
|
||||
@ -103,11 +117,6 @@ public class ZenLog {
|
||||
append(TYPE_CONFIG, newConfig != null ? newConfig.toString() : null);
|
||||
}
|
||||
|
||||
public static void traceFollowRingerMode(int ringerMode, int oldZen, int newZen) {
|
||||
append(TYPE_FOLLOW_RINGER_MODE, ringerModeToString(ringerMode) + ", "
|
||||
+ zenModeToString(oldZen) + " -> " + zenModeToString(newZen));
|
||||
}
|
||||
|
||||
public static void traceDisableEffects(NotificationRecord record, String reason) {
|
||||
append(TYPE_DISABLE_EFFECTS, record.getKey() + "," + reason);
|
||||
}
|
||||
@ -120,7 +129,8 @@ public class ZenLog {
|
||||
switch (type) {
|
||||
case TYPE_INTERCEPTED: return "intercepted";
|
||||
case TYPE_ALLOW_DISABLE: return "allow_disable";
|
||||
case TYPE_SET_RINGER_MODE: return "set_ringer_mode";
|
||||
case TYPE_SET_RINGER_MODE_EXTERNAL: return "set_ringer_mode_external";
|
||||
case TYPE_SET_RINGER_MODE_INTERNAL: return "set_ringer_mode_internal";
|
||||
case TYPE_DOWNTIME: return "downtime";
|
||||
case TYPE_SET_ZEN_MODE: return "set_zen_mode";
|
||||
case TYPE_UPDATE_ZEN_MODE: return "update_zen_mode";
|
||||
@ -128,7 +138,6 @@ public class ZenLog {
|
||||
case TYPE_SUBSCRIBE: return "subscribe";
|
||||
case TYPE_UNSUBSCRIBE: return "unsubscribe";
|
||||
case TYPE_CONFIG: return "config";
|
||||
case TYPE_FOLLOW_RINGER_MODE: return "follow_ringer_mode";
|
||||
case TYPE_NOT_INTERCEPTED: return "not_intercepted";
|
||||
case TYPE_DISABLE_EFFECTS: return "disable_effects";
|
||||
default: return "unknown";
|
||||
|
@ -21,20 +21,20 @@ import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Notification;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.database.ContentObserver;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioManagerInternal;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings.Global;
|
||||
import android.provider.Settings.Secure;
|
||||
@ -45,6 +45,7 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
@ -60,12 +61,12 @@ import java.util.Objects;
|
||||
/**
|
||||
* NotificationManagerService helper for functionality related to zen mode.
|
||||
*/
|
||||
public class ZenModeHelper {
|
||||
public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
|
||||
private static final String TAG = "ZenModeHelper";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final H mHandler;
|
||||
private final SettingsObserver mSettingsObserver;
|
||||
private final AppOpsManager mAppOps;
|
||||
private final ZenModeConfig mDefaultConfig;
|
||||
@ -74,21 +75,17 @@ public class ZenModeHelper {
|
||||
private ComponentName mDefaultPhoneApp;
|
||||
private int mZenMode;
|
||||
private ZenModeConfig mConfig;
|
||||
private AudioManager mAudioManager;
|
||||
private AudioManagerInternal mAudioManager;
|
||||
private int mPreviousRingerMode = -1;
|
||||
|
||||
public ZenModeHelper(Context context, Handler handler) {
|
||||
public ZenModeHelper(Context context, Looper looper) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mHandler = new H(looper);
|
||||
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
||||
mDefaultConfig = readDefaultConfig(context.getResources());
|
||||
mConfig = mDefaultConfig;
|
||||
mSettingsObserver = new SettingsObserver(mHandler);
|
||||
mSettingsObserver.observe();
|
||||
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
|
||||
mContext.registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
public static ZenModeConfig readDefaultConfig(Resources resources) {
|
||||
@ -111,8 +108,11 @@ public class ZenModeHelper {
|
||||
mCallbacks.add(callback);
|
||||
}
|
||||
|
||||
public void setAudioManager(AudioManager audioManager) {
|
||||
mAudioManager = audioManager;
|
||||
public void onSystemReady() {
|
||||
mAudioManager = LocalServices.getService(AudioManagerInternal.class);
|
||||
if (mAudioManager != null) {
|
||||
mAudioManager.setRingerModeDelegate(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int getZenModeListenerInterruptionFilter() {
|
||||
@ -142,10 +142,10 @@ public class ZenModeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public void requestFromListener(int interruptionFilter) {
|
||||
public void requestFromListener(ComponentName name, int interruptionFilter) {
|
||||
final int newZen = zenModeFromListenerInterruptionFilter(interruptionFilter, -1);
|
||||
if (newZen != -1) {
|
||||
setZenMode(newZen, "listener");
|
||||
setZenMode(newZen, "listener:" + (name != null ? name.flattenToShortString() : null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,12 +214,13 @@ public class ZenModeHelper {
|
||||
}
|
||||
|
||||
public void updateZenMode() {
|
||||
final int mode = Global.getInt(mContext.getContentResolver(),
|
||||
final int oldMode = mZenMode;
|
||||
final int newMode = Global.getInt(mContext.getContentResolver(),
|
||||
Global.ZEN_MODE, Global.ZEN_MODE_OFF);
|
||||
if (mode != mZenMode) {
|
||||
ZenLog.traceUpdateZenMode(mZenMode, mode);
|
||||
if (oldMode != newMode) {
|
||||
ZenLog.traceUpdateZenMode(oldMode, newMode);
|
||||
}
|
||||
mZenMode = mode;
|
||||
mZenMode = newMode;
|
||||
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
|
||||
final String[] exceptionPackages = null; // none (for now)
|
||||
|
||||
@ -241,29 +242,7 @@ public class ZenModeHelper {
|
||||
muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
|
||||
exceptionPackages);
|
||||
|
||||
// force ringer mode into compliance
|
||||
if (mAudioManager != null) {
|
||||
int ringerMode = mAudioManager.getRingerMode();
|
||||
int forcedRingerMode = -1;
|
||||
if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
|
||||
if (ringerMode != AudioManager.RINGER_MODE_SILENT) {
|
||||
mPreviousRingerMode = ringerMode;
|
||||
if (DEBUG) Slog.d(TAG, "Silencing ringer");
|
||||
forcedRingerMode = AudioManager.RINGER_MODE_SILENT;
|
||||
}
|
||||
} else {
|
||||
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
if (DEBUG) Slog.d(TAG, "Unsilencing ringer");
|
||||
forcedRingerMode = mPreviousRingerMode != -1 ? mPreviousRingerMode
|
||||
: AudioManager.RINGER_MODE_NORMAL;
|
||||
mPreviousRingerMode = -1;
|
||||
}
|
||||
}
|
||||
if (forcedRingerMode != -1) {
|
||||
mAudioManager.setRingerMode(forcedRingerMode, false /*checkZen*/);
|
||||
ZenLog.traceSetRingerMode(forcedRingerMode);
|
||||
}
|
||||
}
|
||||
onZenUpdated(oldMode, newMode);
|
||||
dispatchOnZenModeChanged();
|
||||
}
|
||||
|
||||
@ -303,25 +282,102 @@ public class ZenModeHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleRingerModeChanged() {
|
||||
if (mAudioManager != null) {
|
||||
// follow ringer mode if necessary
|
||||
final int ringerMode = mAudioManager.getRingerMode();
|
||||
int newZen = -1;
|
||||
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
if (mZenMode == Global.ZEN_MODE_OFF) {
|
||||
newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
private void onZenUpdated(int oldZen, int newZen) {
|
||||
if (mAudioManager == null) return;
|
||||
if (oldZen == newZen) return;
|
||||
|
||||
// force the ringer mode into compliance
|
||||
final int ringerModeInternal = mAudioManager.getRingerModeInternal();
|
||||
int newRingerModeInternal = ringerModeInternal;
|
||||
switch (newZen) {
|
||||
case Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
if (ringerModeInternal != AudioManager.RINGER_MODE_SILENT) {
|
||||
mPreviousRingerMode = ringerModeInternal;
|
||||
newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
|
||||
}
|
||||
} else if ((ringerMode == AudioManager.RINGER_MODE_NORMAL
|
||||
|| ringerMode == AudioManager.RINGER_MODE_VIBRATE)
|
||||
&& mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
|
||||
newZen = Global.ZEN_MODE_OFF;
|
||||
}
|
||||
if (newZen != -1) {
|
||||
ZenLog.traceFollowRingerMode(ringerMode, mZenMode, newZen);
|
||||
setZenMode(newZen, "ringerMode");
|
||||
}
|
||||
break;
|
||||
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
case Global.ZEN_MODE_OFF:
|
||||
if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
|
||||
newRingerModeInternal = mPreviousRingerMode != -1 ? mPreviousRingerMode
|
||||
: AudioManager.RINGER_MODE_NORMAL;
|
||||
mPreviousRingerMode = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (newRingerModeInternal != -1) {
|
||||
mAudioManager.setRingerModeInternal(newRingerModeInternal, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // RingerModeDelegate
|
||||
public int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
|
||||
int ringerModeExternal) {
|
||||
final boolean isChange = ringerModeOld != ringerModeNew;
|
||||
|
||||
int ringerModeExternalOut = ringerModeNew;
|
||||
|
||||
int newZen = -1;
|
||||
switch(ringerModeNew) {
|
||||
case AudioManager.RINGER_MODE_SILENT:
|
||||
if (isChange) {
|
||||
if (mZenMode != Global.ZEN_MODE_NO_INTERRUPTIONS) {
|
||||
newZen = Global.ZEN_MODE_NO_INTERRUPTIONS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AudioManager.RINGER_MODE_VIBRATE:
|
||||
case AudioManager.RINGER_MODE_NORMAL:
|
||||
if (mZenMode != Global.ZEN_MODE_OFF) {
|
||||
ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (newZen != -1) {
|
||||
mHandler.postSetZenMode(newZen, "ringerModeInternal");
|
||||
}
|
||||
|
||||
if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
|
||||
ZenLog.traceSetRingerModeInternal(ringerModeOld, ringerModeNew, caller,
|
||||
ringerModeExternal, ringerModeExternalOut);
|
||||
}
|
||||
return ringerModeExternalOut;
|
||||
}
|
||||
|
||||
@Override // RingerModeDelegate
|
||||
public int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
|
||||
int ringerModeInternal) {
|
||||
int ringerModeInternalOut = ringerModeNew;
|
||||
final boolean isChange = ringerModeOld != ringerModeNew;
|
||||
final boolean isVibrate = ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
|
||||
|
||||
int newZen = -1;
|
||||
switch(ringerModeNew) {
|
||||
case AudioManager.RINGER_MODE_SILENT:
|
||||
if (isChange) {
|
||||
if (mZenMode == Global.ZEN_MODE_OFF) {
|
||||
newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
}
|
||||
ringerModeInternalOut = isVibrate ? AudioManager.RINGER_MODE_VIBRATE
|
||||
: AudioManager.RINGER_MODE_NORMAL;
|
||||
} else {
|
||||
ringerModeInternalOut = ringerModeInternal;
|
||||
}
|
||||
break;
|
||||
case AudioManager.RINGER_MODE_VIBRATE:
|
||||
case AudioManager.RINGER_MODE_NORMAL:
|
||||
if (mZenMode != Global.ZEN_MODE_OFF) {
|
||||
newZen = Global.ZEN_MODE_OFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (newZen != -1) {
|
||||
mHandler.postSetZenMode(newZen, "ringerModeExternal");
|
||||
}
|
||||
|
||||
ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller, ringerModeInternal,
|
||||
ringerModeInternalOut);
|
||||
return ringerModeInternalOut;
|
||||
}
|
||||
|
||||
private void dispatchOnConfigChanged() {
|
||||
@ -399,6 +455,11 @@ public class ZenModeHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
private boolean audienceMatches(float contactAffinity) {
|
||||
switch (mConfig.allowFrom) {
|
||||
case ZenModeConfig.SOURCE_ANYONE:
|
||||
@ -413,13 +474,6 @@ public class ZenModeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mRingerModeChanged = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleRingerModeChanged();
|
||||
}
|
||||
};
|
||||
|
||||
private class SettingsObserver extends ContentObserver {
|
||||
private final Uri ZEN_MODE = Global.getUriFor(Global.ZEN_MODE);
|
||||
|
||||
@ -445,12 +499,26 @@ public class ZenModeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mHandler.post(mRingerModeChanged);
|
||||
private class H extends Handler {
|
||||
private static final int MSG_SET_ZEN = 1;
|
||||
|
||||
private H(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
};
|
||||
|
||||
private void postSetZenMode(int zen, String reason) {
|
||||
obtainMessage(MSG_SET_ZEN, zen, 0, reason).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch(msg.what) {
|
||||
case MSG_SET_ZEN:
|
||||
setZenMode(msg.arg1, (String) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Callback {
|
||||
void onConfigChanged() {}
|
||||
|
Reference in New Issue
Block a user