summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java20
-rw-r--r--data/fonts/fallback_fonts.xml5
-rw-r--r--data/fonts/fonts.xml3
-rw-r--r--libs/hwui/RenderNode.cpp7
-rw-r--r--libs/hwui/RenderProperties.h2
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp3
-rw-r--r--libs/hwui/tests/Android.mk1
-rw-r--r--media/java/android/media/AudioManager.java81
-rw-r--r--media/java/android/media/AudioManagerInternal.java16
-rw-r--r--media/java/android/media/AudioService.java192
-rw-r--r--media/java/android/media/IAudioService.aidl8
-rw-r--r--media/java/android/media/IVolumeController.aidl2
-rw-r--r--media/java/android/media/MediaCodec.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/IconPulser.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java162
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java21
-rw-r--r--services/core/java/com/android/server/location/GpsLocationProvider.java5
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java12
-rw-r--r--services/core/java/com/android/server/notification/ZenLog.java45
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java210
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java54
-rw-r--r--services/java/com/android/server/SystemServer.java30
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java47
32 files changed, 820 insertions, 306 deletions
diff --git a/api/current.txt b/api/current.txt
index 27b107a..707ddab 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5441,6 +5441,7 @@ package android.app.admin {
field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
+ field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
}
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d00cbb7..0e1c85c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1473,22 +1473,30 @@ public class DevicePolicyManager {
/**
* Flag for {@link #wipeData(int)}: also erase the device's external
- * storage.
+ * storage (such as SD cards).
*/
public static final int WIPE_EXTERNAL_STORAGE = 0x0001;
/**
+ * Flag for {@link #wipeData(int)}: also erase the factory reset protection
+ * data.
+ *
+ * This flag may only be set by device owner admins; if it is set by other
+ * admins a {@link SecurityException} will be thrown.
+ */
+ public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
+
+ /**
* Ask the user data be wiped. This will cause the device to reboot,
- * erasing all user data while next booting up. External storage such
- * as SD cards will be also erased if the flag {@link #WIPE_EXTERNAL_STORAGE}
- * is set.
+ * erasing all user data while next booting up.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
* this method; if it has not, a security exception will be thrown.
*
- * @param flags Bit mask of additional options: currently 0 and
- * {@link #WIPE_EXTERNAL_STORAGE} are supported.
+ * @param flags Bit mask of additional options: currently supported flags
+ * are {@link #WIPE_EXTERNAL_STORAGE} and
+ * {@link #WIPE_RESET_PROTECTION_DATA}.
*/
public void wipeData(int flags) {
if (mService != null) {
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 4b38ad3..0244891 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -319,6 +319,11 @@
</family>
<family>
<fileset>
+ <file>Lohit-Odia.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
<file lang="zh-Hans">NotoSansHans-Regular.otf</file>
</fileset>
</family>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 4493554..a62e972 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -277,6 +277,9 @@
<family>
<font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
</family>
+ <family>
+ <font weight="400" style="normal">Lohit-Odia.ttf</font>
+ </family>
<family lang="zh-Hans">
<font weight="400" style="normal">NotoSansHans-Regular.otf</font>
</family>
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index eb0948f..bbba2dd 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -105,8 +105,11 @@ void RenderNode::setStagingDisplayList(DisplayListData* data) {
* display list. This function should remain in sync with the replay() function.
*/
void RenderNode::output(uint32_t level) {
- ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
- getName(), isRenderable());
+ ALOGD("%*sStart display list (%p, %s%s%s%s)", (level - 1) * 2, "", this,
+ getName(),
+ (properties().hasShadow() ? ", casting shadow" : ""),
+ (isRenderable() ? "" : ", empty"),
+ (mLayer != NULL ? ", on HW Layer" : ""));
ALOGD("%*s%s %d", level * 2, "", "Save",
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index b936d4b..31c4f22 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -570,7 +570,7 @@ public:
}
bool hasShadow() const {
- return getZ() >= 0.0f
+ return getZ() > 0.0f
&& getOutline().getPath() != NULL
&& getOutline().getAlpha() != 0.0f;
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 39528be..4f39ac9 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -60,6 +60,8 @@ CanvasContext::~CanvasContext() {
void CanvasContext::destroy() {
stopDrawing();
+ setSurface(NULL);
+ mEglManager.usePBufferSurface();
freePrefetechedLayers();
destroyHardwareResources();
mAnimationContext->destroy();
@@ -67,7 +69,6 @@ void CanvasContext::destroy() {
delete mCanvas;
mCanvas = 0;
}
- setSurface(NULL);
}
void CanvasContext::setSurface(ANativeWindow* window) {
diff --git a/libs/hwui/tests/Android.mk b/libs/hwui/tests/Android.mk
index 9622073..7bdce7f 100644
--- a/libs/hwui/tests/Android.mk
+++ b/libs/hwui/tests/Android.mk
@@ -19,6 +19,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
+LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
LOCAL_SRC_FILES:= \
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3f08305..0642bcd 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -470,6 +470,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);
}
@@ -3308,6 +3342,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.
*
* @param on whether to be on system audio mode
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index a6cc493..d9586bc 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -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);
+ }
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b6b24a4..e5ae93c 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -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
///////////////////////////////////////////////////////////////////////////
@@ -546,7 +548,7 @@ public class AudioService extends IAudioService.Stub {
com.android.internal.R.bool.config_voice_capable)) {
mPlatformType = PLATFORM_VOICE;
} else if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TELEVISION)) {
+ PackageManager.FEATURE_LEANBACK)) {
mPlatformType = PLATFORM_TELEVISION;
} else {
mPlatformType = PLATFORM_DEFAULT;
@@ -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,
@@ -5346,7 +5386,7 @@ public class AudioService extends IAudioService.Stub {
private boolean mHdmiSystemAudioSupported = false;
// Set only when device is tv.
private HdmiTvClient mHdmiTvClient;
- // true if the device has system feature PackageManager.FEATURE_TELEVISION.
+ // true if the device has system feature PackageManager.FEATURE_LEANBACK.
// cached HdmiControlManager interface
private HdmiControlManager mHdmiManager;
// Set only when device is a set-top box.
@@ -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);
+ }
}
//==========================================================================================
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index b691447..4d8aa76 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -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);
diff --git a/media/java/android/media/IVolumeController.aidl b/media/java/android/media/IVolumeController.aidl
index e3593a6..c31d80c 100644
--- a/media/java/android/media/IVolumeController.aidl
+++ b/media/java/android/media/IVolumeController.aidl
@@ -34,4 +34,6 @@ oneway interface IVolumeController {
void setLayoutDirection(int layoutDirection);
void dismiss();
+
+ void internalRingerModeChanged(int mode);
}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index bdd62f2..8985b52 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -1784,11 +1784,11 @@ final public class MediaCodec {
mYOffset = yOffset;
mInfo = info;
- // read media-info. the size of media info can be 80 or 156 depending on
+ // read media-info. the size of media info can be 80 or 156/160 depending on
// whether it was created on a 32- or 64-bit process. See MediaImage
- if (info.remaining() == 80 || info.remaining() == 156) {
- boolean sizeIsLong = info.remaining() == 156;
- int type = info.getInt();
+ if (info.remaining() == 80 || info.remaining() == 156 || info.remaining() == 160) {
+ boolean sizeIsLong = info.remaining() != 80;
+ int type = readInt(info, info.remaining() == 160);
if (type != TYPE_YUV) {
throw new UnsupportedOperationException("unsupported type: " + type);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9246f4d..54eb18c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -53,6 +53,7 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
@@ -267,6 +268,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private UnlockMethodCache mUnlockMethodCache;
private DozeServiceHost mDozeServiceHost;
private boolean mScreenOnComingFromTouch;
+ private PointF mScreenOnTouchLocation;
int mPixelFormat;
Object mQueueLock = new Object();
@@ -1028,6 +1030,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,
@@ -3705,7 +3713,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
boolean animate = !mDozing && mDozeScrimController.isPulsing();
mNotificationPanel.setDozing(mDozing, animate);
- mStackScroller.setDark(mDozing, animate);
+ mStackScroller.setDark(mDozing, animate, mScreenOnTouchLocation);
mScrimController.setDozing(mDozing);
mDozeScrimController.setDozing(mDozing, animate);
}
@@ -3961,6 +3969,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void onScreenTurnedOff() {
mScreenOnFromKeyguard = false;
mScreenOnComingFromTouch = false;
+ mScreenOnTouchLocation = null;
mStackScroller.setAnimationsEnabled(false);
updateVisibleToUser();
}
@@ -4083,14 +4092,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return !mNotificationData.getActiveNotifications().isEmpty();
}
- public void wakeUpIfDozing(long time, boolean fromTouch) {
+ public void wakeUpIfDozing(long time, MotionEvent event) {
if (mDozing && mDozeScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(time);
- if (fromTouch) {
- mScreenOnComingFromTouch = true;
- mNotificationPanel.setTouchDisabled(false);
- }
+ mScreenOnComingFromTouch = true;
+ mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
+ mNotificationPanel.setTouchDisabled(false);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 60d23ce..94401d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -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);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 47ec08d..a96f4e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -173,7 +173,7 @@ public class StatusBarWindowView extends FrameLayout {
intercept = mDragDownHelper.onInterceptTouchEvent(ev);
// wake up on a touch down event, if dozing
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mService.wakeUpIfDozing(ev.getEventTime(), true);
+ mService.wakeUpIfDozing(ev.getEventTime(), ev);
}
}
if (!intercept) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 415eb27..37ed7d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -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();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 3d4cda6..753a7f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -34,6 +34,7 @@ public class AnimationFilter {
boolean hasDelays;
boolean hasGoToFullShadeEvent;
boolean hasDarkEvent;
+ int darkAnimationOriginIndex;
public AnimationFilter animateAlpha() {
animateAlpha = true;
@@ -94,14 +95,16 @@ public class AnimationFilter {
reset();
int size = events.size();
for (int i = 0; i < size; i++) {
+ NotificationStackScrollLayout.AnimationEvent ev = events.get(i);
combineFilter(events.get(i).filter);
- if (events.get(i).animationType ==
+ if (ev.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
hasGoToFullShadeEvent = true;
}
- if (events.get(i).animationType ==
+ if (ev.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_DARK) {
hasDarkEvent = true;
+ darkAnimationOriginIndex = ev.darkAnimationOriginIndex;
}
}
}
@@ -132,5 +135,7 @@ public class AnimationFilter {
hasDelays = false;
hasGoToFullShadeEvent = false;
hasDarkEvent = false;
+ darkAnimationOriginIndex =
+ NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 16ff3dc..2a393bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -16,10 +16,12 @@
package com.android.systemui.statusbar.stack;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -149,6 +151,7 @@ public class NotificationStackScrollLayout extends ViewGroup
private boolean mDimmedNeedsAnimation;
private boolean mHideSensitiveNeedsAnimation;
private boolean mDarkNeedsAnimation;
+ private int mDarkAnimationOriginIndex;
private boolean mActivateNeedsAnimation;
private boolean mGoToFullShadeNeedsAnimation;
private boolean mIsExpanded = true;
@@ -210,6 +213,7 @@ public class NotificationStackScrollLayout extends ViewGroup
}
};
private PhoneStatusBar mPhoneStatusBar;
+ private int[] mTempInt2 = new int[2];
public NotificationStackScrollLayout(Context context) {
this(context, null);
@@ -587,10 +591,38 @@ public class NotificationStackScrollLayout extends ViewGroup
return getChildAtPosition(ev.getX(), ev.getY());
}
+ public ExpandableView getClosestChildAtRawPosition(float touchX, float touchY) {
+ getLocationOnScreen(mTempInt2);
+ float localTouchY = touchY - mTempInt2[1];
+
+ ExpandableView closestChild = null;
+ float minDist = Float.MAX_VALUE;
+
+ // find the view closest to the location, accounting for GONE views
+ final int count = getChildCount();
+ for (int childIdx = 0; childIdx < count; childIdx++) {
+ ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
+ if (slidingChild.getVisibility() == GONE
+ || slidingChild instanceof StackScrollerDecorView
+ || slidingChild == mSpeedBumpView) {
+ continue;
+ }
+ float childTop = slidingChild.getTranslationY();
+ float top = childTop + slidingChild.getClipTopAmount();
+ float bottom = childTop + slidingChild.getActualHeight();
+
+ float dist = Math.min(Math.abs(top - localTouchY), Math.abs(bottom - localTouchY));
+ if (dist < minDist) {
+ closestChild = slidingChild;
+ minDist = dist;
+ }
+ }
+ return closestChild;
+ }
+
public ExpandableView getChildAtRawPosition(float touchX, float touchY) {
- int[] location = new int[2];
- getLocationOnScreen(location);
- return getChildAtPosition(touchX - location[0], touchY - location[1]);
+ getLocationOnScreen(mTempInt2);
+ return getChildAtPosition(touchX - mTempInt2[0], touchY - mTempInt2[1]);
}
public ExpandableView getChildAtPosition(float touchX, float touchY) {
@@ -1818,8 +1850,9 @@ public class NotificationStackScrollLayout extends ViewGroup
private void generateDarkEvent() {
if (mDarkNeedsAnimation) {
- mAnimationEvents.add(
- new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_DARK));
+ AnimationEvent ev = new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_DARK);
+ ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex;
+ mAnimationEvents.add(ev);
}
mDarkNeedsAnimation = false;
}
@@ -2151,7 +2184,7 @@ public class NotificationStackScrollLayout extends ViewGroup
mEmptyShadeView.setInvisible();
mGoToFullShadeNeedsAnimation = true;
mGoToFullShadeDelay = delay;
- mNeedsAnimation = true;
+ mNeedsAnimation = true;
requestChildrenUpdate();
}
@@ -2182,15 +2215,46 @@ public class NotificationStackScrollLayout extends ViewGroup
/**
* See {@link AmbientState#setDark}.
*/
- public void setDark(boolean dark, boolean animate) {
+ public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
mAmbientState.setDark(dark);
if (animate && mAnimationsEnabled) {
mDarkNeedsAnimation = true;
+ mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation);
mNeedsAnimation = true;
}
requestChildrenUpdate();
}
+ private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
+ if (screenLocation == null || screenLocation.y < mTopPadding + mTopPaddingOverflow) {
+ return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
+ }
+ if (screenLocation.y > getBottomMostNotificationBottom()) {
+ return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW;
+ }
+ View child = getClosestChildAtRawPosition(screenLocation.x, screenLocation.y);
+ if (child != null) {
+ return getNotGoneIndex(child);
+ } else {
+ return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
+ }
+ }
+
+ private int getNotGoneIndex(View child) {
+ int count = getChildCount();
+ int notGoneIndex = 0;
+ for (int i = 0; i < count; i++) {
+ View v = getChildAt(i);
+ if (child == v) {
+ return notGoneIndex;
+ }
+ if (v.getVisibility() != View.GONE) {
+ notGoneIndex++;
+ }
+ }
+ return -1;
+ }
+
public void setDismissView(DismissView dismissView) {
mDismissView = dismissView;
addView(mDismissView);
@@ -2556,12 +2620,16 @@ public class NotificationStackScrollLayout extends ViewGroup
static final int ANIMATION_TYPE_VIEW_RESIZE = 12;
static final int ANIMATION_TYPE_EVERYTHING = 13;
+ static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
+ static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
+
final long eventStartTime;
final View changingView;
final int animationType;
final AnimationFilter filter;
final long length;
View viewAfterChangingView;
+ int darkAnimationOriginIndex;
AnimationEvent(View view, int type) {
this(view, type, LENGTHS[type]);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 05077bf..b027787 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -315,7 +315,17 @@ public class StackStateAnimator {
}
private long calculateDelayDark(StackScrollState.ViewState viewState) {
- return viewState.notGoneIndex * ANIMATION_DELAY_PER_ELEMENT_DARK;
+ int referenceIndex;
+ if (mAnimationFilter.darkAnimationOriginIndex ==
+ NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE) {
+ referenceIndex = 0;
+ } else if (mAnimationFilter.darkAnimationOriginIndex ==
+ NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW) {
+ referenceIndex = mHostLayout.getNotGoneChildCount() - 1;
+ } else {
+ referenceIndex = mAnimationFilter.darkAnimationOriginIndex;
+ }
+ return Math.abs(referenceIndex - viewState.notGoneIndex) * ANIMATION_DELAY_PER_ELEMENT_DARK;
}
private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java b/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java
new file mode 100644
index 0000000..9438af1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java
@@ -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);
+ }
+ });
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 351911c..1fe4698 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -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);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 7102c2a..e452b22 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -182,6 +182,15 @@ public class VolumeUI extends SystemUI {
}
@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();
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 5b37f78..b84b138 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -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) {
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index c960c07..9c0f987 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -788,8 +788,9 @@ public class GpsLocationProvider implements LocationProviderInterface {
}
if (info != null) {
- boolean dataEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.MOBILE_DATA, 1) == 1;
+ boolean dataEnabled = TelephonyManager.getIntWithSubId(mContext.getContentResolver(),
+ Settings.Global.MOBILE_DATA, SubscriptionManager.getDefaultSubId(),
+ 1) == 1;
boolean networkAvailable = info.isAvailable() && dataEnabled;
String defaultApn = getSelectedApn();
if (defaultApn == null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d60c57f..70d0e6a 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -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;
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 1a3da79..6960159 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -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";
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 992b6aa..5ceb503 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -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() {
+ 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 onReceive(Context context, Intent intent) {
- mHandler.post(mRingerModeChanged);
+ 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() {}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6331dfe..2201d2b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -17,6 +17,8 @@
package com.android.server.devicepolicy;
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
+import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
+import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
import android.accessibilityservice.AccessibilityServiceInfo;
@@ -78,6 +80,7 @@ import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.text.TextUtils;
+import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -96,7 +99,6 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
-import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
@@ -1645,12 +1647,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private void manageNotification(UserHandle userHandle) {
+ final UserInfo userInfo = mUserManager.getUserInfo(userHandle.getIdentifier());
+
+ // Inactive users or managed profiles shouldn't provoke a warning
if (!mUserManager.isUserRunning(userHandle)) {
return;
}
+ if (userInfo == null || userInfo.isManagedProfile()) {
+ return;
+ }
+ // Call out to KeyChain to check for user-added CAs
boolean hasCert = false;
- final long id = Binder.clearCallingIdentity();
try {
KeyChainConnection kcs = KeyChain.bindAsUser(mContext, userHandle);
try {
@@ -1666,8 +1674,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Thread.currentThread().interrupt();
} catch (RuntimeException e) {
Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
- } finally {
- Binder.restoreCallingIdentity(id);
}
if (!hasCert) {
getNotificationManager().cancelAsUser(
@@ -1675,6 +1681,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
+ // Build and show a warning notification
int smallIconId;
String contentText;
final String ownerName = getDeviceOwnerName();
@@ -2925,10 +2932,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
- void wipeDataLocked(int flags, String reason) {
+ private void wipeDataLocked(boolean wipeExtRequested, String reason) {
// If the SD card is encrypted and non-removable, we have to force a wipe.
boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
- boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
// Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
@@ -2941,9 +2947,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else {
try {
RecoverySystem.rebootWipeUserData(mContext, reason);
- } catch (IOException e) {
- Slog.w(LOG_TAG, "Failed requesting data wipe", e);
- } catch (SecurityException e) {
+ } catch (IOException | SecurityException e) {
Slog.w(LOG_TAG, "Failed requesting data wipe", e);
}
}
@@ -2962,20 +2966,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DeviceAdminInfo.USES_POLICY_WIPE_DATA);
final String source;
- if (admin != null && admin.info != null) {
- final ComponentName cname = admin.info.getComponent();
- if (cname != null) {
- source = cname.flattenToShortString();
- } else {
- source = admin.info.getPackageName();
- }
+ final ComponentName cname = admin.info.getComponent();
+ if (cname != null) {
+ source = cname.flattenToShortString();
} else {
- source = "?";
+ source = admin.info.getPackageName();
}
long ident = Binder.clearCallingIdentity();
try {
- wipeDeviceOrUserLocked(flags, userHandle,
+ if ((flags & WIPE_RESET_PROTECTION_DATA) != 0) {
+ if (userHandle != UserHandle.USER_OWNER
+ || !isDeviceOwner(admin.info.getPackageName())) {
+ throw new SecurityException(
+ "Only device owner admins can set WIPE_RESET_PROTECTION_DATA");
+ }
+ PersistentDataBlockManager manager = (PersistentDataBlockManager)
+ mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+ manager.wipe();
+ }
+ boolean wipeExtRequested = (flags & WIPE_EXTERNAL_STORAGE) != 0;
+ wipeDeviceOrUserLocked(wipeExtRequested, userHandle,
"DevicePolicyManager.wipeData() from " + source);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2983,9 +2994,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- private void wipeDeviceOrUserLocked(int flags, final int userHandle, String reason) {
+ private void wipeDeviceOrUserLocked(boolean wipeExtRequested, final int userHandle, String reason) {
if (userHandle == UserHandle.USER_OWNER) {
- wipeDataLocked(flags, reason);
+ wipeDataLocked(wipeExtRequested, reason);
} else {
mHandler.post(new Runnable() {
public void run() {
@@ -3137,7 +3148,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
if (wipeData) {
// Call without holding lock.
- wipeDeviceOrUserLocked(0, identifier, "reportFailedPasswordAttempt()");
+ wipeDeviceOrUserLocked(false, identifier,
+ "reportFailedPasswordAttempt()");
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4e6a8ea..b3a696e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -549,20 +549,6 @@ public final class SystemServer {
reportWtf("making display ready", e);
}
- try {
- mPackageManagerService.performBootDexOpt();
- } catch (Throwable e) {
- reportWtf("performing boot dexopt", e);
- }
-
- try {
- ActivityManagerNative.getDefault().showBootMessage(
- context.getResources().getText(
- com.android.internal.R.string.android_upgrading_starting_apps),
- false);
- } catch (RemoteException e) {
- }
-
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
if (!disableStorage &&
!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
@@ -578,7 +564,23 @@ public final class SystemServer {
reportWtf("starting Mount Service", e);
}
}
+ }
+ try {
+ mPackageManagerService.performBootDexOpt();
+ } catch (Throwable e) {
+ reportWtf("performing boot dexopt", e);
+ }
+
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ context.getResources().getText(
+ com.android.internal.R.string.android_upgrading_starting_apps),
+ false);
+ } catch (RemoteException e) {
+ }
+
+ if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
if (!disableNonCoreServices) {
try {
Slog.i(TAG, "LockSettingsService");
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 40a8ed4..868b770 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -19,8 +19,11 @@ package android.telephony;
import android.annotation.SystemApi;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -3524,4 +3527,48 @@ public class TelephonyManager {
}
return false;
}
+
+ /**
+ * This function retrieves value for setting "name+subId", and if that is not found
+ * retrieves value for setting "name", and if that is not found uses def as default
+ *
+ * @hide */
+ public static int getIntWithSubId(ContentResolver cr, String name, int subId, int def) {
+ return Settings.Global.getInt(cr, name + subId, Settings.Global.getInt(cr, name, def));
+ }
+
+ /**
+ * This function retrieves value for setting "name+subId", and if that is not found
+ * retrieves value for setting "name", and if that is not found throws
+ * SettingNotFoundException
+ *
+ * @hide */
+ public static int getIntWithSubId(ContentResolver cr, String name, int subId)
+ throws SettingNotFoundException {
+ try {
+ return Settings.Global.getInt(cr, name + subId);
+ } catch (SettingNotFoundException e) {
+ try {
+ int val = Settings.Global.getInt(cr, name);
+ /* We are now moving from 'setting' to 'setting+subId', and using the value stored
+ * for 'setting' as default. Reset the default (since it may have a user set
+ * value). */
+ int default_val = val;
+ if (name.equals(Settings.Global.MOBILE_DATA)) {
+ default_val = "true".equalsIgnoreCase(
+ SystemProperties.get("ro.com.android.mobiledata", "true")) ? 1 : 0;
+ }
+
+ if (default_val != val) {
+ Settings.Global.putInt(cr, name, default_val);
+ }
+
+ return val;
+ } catch (SettingNotFoundException exc) {
+ throw new SettingNotFoundException(name);
+ }
+ }
+ }
}
+
+