Merge "Add lock task checking to moving tasks to back" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index fc042d2..c0752d0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5424,7 +5424,7 @@
     method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
     method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
-    method public java.util.List<byte[]> getInstalledCaCerts();
+    method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
     method public long getMaximumTimeToLock(android.content.ComponentName);
@@ -5445,7 +5445,7 @@
     method public boolean getScreenCaptureDisabled(android.content.ComponentName);
     method public boolean getStorageEncryption(android.content.ComponentName);
     method public int getStorageEncryptionStatus();
-    method public boolean hasCaCertInstalled(byte[]);
+    method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
     method public boolean isActivePasswordSufficient();
@@ -28859,7 +28859,7 @@
     method public boolean getAutoPersisting();
     method public android.os.Bundle getCarrierConfigValues();
     method public static android.telephony.SmsManager getDefault();
-    method public static android.telephony.SmsManager getSmsManagerForSubId(long);
+    method public static android.telephony.SmsManager getSmsManagerUsingSubId(long);
     method public long getSubId();
     method public android.net.Uri importMultimediaMessage(byte[], java.lang.String, long, boolean, boolean);
     method public android.net.Uri importTextMessage(java.lang.String, int, java.lang.String, long, boolean, boolean);
@@ -28876,6 +28876,8 @@
     method public void updateMmsSendStatus(int, boolean);
     method public void updateSmsSendStatus(int, boolean);
     method public boolean updateStoredMessageStatus(android.net.Uri, android.content.ContentValues);
+    field public static final java.lang.String MESSAGE_STATUS_READ = "read";
+    field public static final java.lang.String MESSAGE_STATUS_SEEN = "seen";
     field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
     field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
     field public static final java.lang.String MMS_CONFIG_ALIAS_MIN_CHARS = "aliasMinChars";
@@ -28904,8 +28906,6 @@
     field public static final java.lang.String MMS_CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
     field public static final java.lang.String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
     field public static final java.lang.String MMS_CONFIG_USER_AGENT = "userAgent";
-    field public static final java.lang.String MESSAGE_STATUS_READ = "read";
-    field public static final java.lang.String MESSAGE_STATUS_SEEN = "seen";
     field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
     field public static final int MMS_ERROR_INVALID_APN = 2; // 0x2
     field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
@@ -32916,6 +32916,7 @@
     field public static final int KEYCODE_GUIDE = 172; // 0xac
     field public static final int KEYCODE_H = 36; // 0x24
     field public static final int KEYCODE_HEADSETHOOK = 79; // 0x4f
+    field public static final int KEYCODE_HELP = 259; // 0x103
     field public static final int KEYCODE_HENKAN = 214; // 0xd6
     field public static final int KEYCODE_HOME = 3; // 0x3
     field public static final int KEYCODE_I = 37; // 0x25
@@ -33016,9 +33017,36 @@
     field public static final int KEYCODE_T = 48; // 0x30
     field public static final int KEYCODE_TAB = 61; // 0x3d
     field public static final int KEYCODE_TV = 170; // 0xaa
+    field public static final int KEYCODE_TV_ANTENNA_CABLE = 242; // 0xf2
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION = 252; // 0xfc
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254; // 0xfe
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253; // 0xfd
+    field public static final int KEYCODE_TV_CONTENTS_MENU = 256; // 0x100
     field public static final int KEYCODE_TV_DATA_SERVICE = 230; // 0xe6
     field public static final int KEYCODE_TV_INPUT = 178; // 0xb2
+    field public static final int KEYCODE_TV_INPUT_COMPONENT_1 = 249; // 0xf9
+    field public static final int KEYCODE_TV_INPUT_COMPONENT_2 = 250; // 0xfa
+    field public static final int KEYCODE_TV_INPUT_COMPOSITE_1 = 247; // 0xf7
+    field public static final int KEYCODE_TV_INPUT_COMPOSITE_2 = 248; // 0xf8
+    field public static final int KEYCODE_TV_INPUT_HDMI_1 = 243; // 0xf3
+    field public static final int KEYCODE_TV_INPUT_HDMI_2 = 244; // 0xf4
+    field public static final int KEYCODE_TV_INPUT_HDMI_3 = 245; // 0xf5
+    field public static final int KEYCODE_TV_INPUT_HDMI_4 = 246; // 0xf6
+    field public static final int KEYCODE_TV_INPUT_VGA_1 = 251; // 0xfb
+    field public static final int KEYCODE_TV_MEDIA_CONTEXT_MENU = 257; // 0x101
+    field public static final int KEYCODE_TV_NETWORK = 241; // 0xf1
+    field public static final int KEYCODE_TV_NUMBER_ENTRY = 234; // 0xea
     field public static final int KEYCODE_TV_POWER = 177; // 0xb1
+    field public static final int KEYCODE_TV_RADIO_SERVICE = 232; // 0xe8
+    field public static final int KEYCODE_TV_SATELLITE = 237; // 0xed
+    field public static final int KEYCODE_TV_SATELLITE_BS = 238; // 0xee
+    field public static final int KEYCODE_TV_SATELLITE_CS = 239; // 0xef
+    field public static final int KEYCODE_TV_SATELLITE_SERVICE = 240; // 0xf0
+    field public static final int KEYCODE_TV_TELETEXT = 233; // 0xe9
+    field public static final int KEYCODE_TV_TERRESTRIAL_ANALOG = 235; // 0xeb
+    field public static final int KEYCODE_TV_TERRESTRIAL_DIGITAL = 236; // 0xec
+    field public static final int KEYCODE_TV_TIMER_PROGRAMMING = 258; // 0x102
+    field public static final int KEYCODE_TV_ZOOM_MODE = 255; // 0xff
     field public static final int KEYCODE_U = 49; // 0x31
     field public static final int KEYCODE_UNKNOWN = 0; // 0x0
     field public static final int KEYCODE_V = 50; // 0x32
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 613e248..ad4a22b 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -151,6 +151,7 @@
             mEnterActivityOptions = options;
             mIsEnterTriggered = false;
             if (mEnterActivityOptions.isReturning()) {
+                restoreExitedViews();
                 int result = mEnterActivityOptions.getResultCode();
                 if (result != 0) {
                     activity.onActivityReenter(result, mEnterActivityOptions.getResultData());
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 47d3fd6..4126647 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -170,7 +170,7 @@
 
     private void sendSharedElementDestination() {
         boolean allReady;
-        if (allowOverlappingTransitions()) {
+        if (allowOverlappingTransitions() && getEnterViewsTransition() != null) {
             allReady = false;
         } else {
             allReady = !getDecor().isLayoutRequested();
@@ -466,6 +466,7 @@
             Drawable background = getDecor().getBackground();
             if (background != null) {
                 background = background.mutate();
+                getWindow().setBackgroundDrawable(background);
                 mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 255);
                 mBackgroundAnimator.setDuration(getFadeDuration());
                 mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 3760b96..231c93f 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -140,7 +140,8 @@
         if (getDecor() != null) {
             getDecor().suppressLayout(true);
         }
-        if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) {
+        if (mExitSharedElementBundle != null && !mExitSharedElementBundle.isEmpty() &&
+                !mSharedElements.isEmpty() && getSharedElementTransition() != null) {
             startTransition(new Runnable() {
                 public void run() {
                     startSharedElementExit();
@@ -259,6 +260,8 @@
             ViewGroup decor = getDecor();
             Drawable background;
             if (decor != null && (background = decor.getBackground()) != null) {
+                background = background.mutate();
+                getWindow().setBackgroundDrawable(background);
                 mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 0);
                 mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
                     @Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9ed8960..282444a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -115,13 +115,14 @@
         = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
 
     /**
-     * A {@link Parcelable} extra of type {@link PersistableBundle} that allows a mobile device
-     * management application that starts managed profile provisioning to pass data to itself on the
-     * managed profile when provisioning completes. The mobile device management application sends
-     * this extra in an intent with the action {@link #ACTION_PROVISION_MANAGED_PROFILE} and
-     * receives it in {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with
-     * the action {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. The bundle is
-     * not changed during the managed profile provisioning.
+     * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that allows
+     * a mobile device management application that starts managed profile provisioning to pass data
+     * to itself on the managed profile when provisioning completes. The mobile device management
+     * application sends this extra in an intent with the action
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} and receives it in
+     * {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. The bundle is not changed
+     * during the managed profile provisioning.
      */
     public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE =
             "android.app.extra.ADMIN_EXTRA_BUNDLE";
@@ -1785,16 +1786,24 @@
      * If a user has installed any certificates by other means than device policy these will be
      * included too.
      *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return a List of byte[] arrays, each encoding one user CA certificate.
      */
-    public List<byte[]> getInstalledCaCerts() {
-        final TrustedCertificateStore certStore = new TrustedCertificateStore();
+    public List<byte[]> getInstalledCaCerts(ComponentName admin) {
         List<byte[]> certs = new ArrayList<byte[]>();
-        for (String alias : certStore.userAliases()) {
+        if (mService != null) {
             try {
-                certs.add(certStore.getCertificate(alias).getEncoded());
-            } catch (CertificateException ce) {
-                Log.w(TAG, "Could not encode certificate: " + alias, ce);
+                mService.enforceCanManageCaCerts(admin);
+                final TrustedCertificateStore certStore = new TrustedCertificateStore();
+                for (String alias : certStore.userAliases()) {
+                    try {
+                        certs.add(certStore.getCertificate(alias).getEncoded());
+                    } catch (CertificateException ce) {
+                        Log.w(TAG, "Could not encode certificate: " + alias, ce);
+                    }
+                }
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
             }
         }
         return certs;
@@ -1821,13 +1830,19 @@
     /**
      * Returns whether this certificate is installed as a trusted CA.
      *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param certBuffer encoded form of the certificate to look up.
      */
-    public boolean hasCaCertInstalled(byte[] certBuffer) {
-        try {
-            return getCaCertAlias(certBuffer) != null;
-        } catch (CertificateException ce) {
-            Log.w(TAG, "Could not parse certificate", ce);
+    public boolean hasCaCertInstalled(ComponentName admin, byte[] certBuffer) {
+        if (mService != null) {
+            try {
+                mService.enforceCanManageCaCerts(admin);
+                return getCaCertAlias(certBuffer) != null;
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            } catch (CertificateException ce) {
+                Log.w(TAG, "Could not parse certificate", ce);
+            }
         }
         return false;
     }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c984cf9..57d8b95 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -124,6 +124,7 @@
 
     boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
     void uninstallCaCert(in ComponentName admin, in String alias);
+    void enforceCanManageCaCerts(in ComponentName admin);
 
     void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
     void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
diff --git a/core/java/android/transition/ChangeTransform.java b/core/java/android/transition/ChangeTransform.java
index d579f54..cb0a875 100644
--- a/core/java/android/transition/ChangeTransform.java
+++ b/core/java/android/transition/ChangeTransform.java
@@ -45,6 +45,10 @@
     private static final String PROPNAME_TRANSFORMS = "android:changeTransform:transforms";
     private static final String PROPNAME_PARENT = "android:changeTransform:parent";
     private static final String PROPNAME_PARENT_MATRIX = "android:changeTransform:parentMatrix";
+    private static final String PROPNAME_INTERMEDIATE_PARENT_MATRIX =
+            "android:changeTransform:intermediateParentMatrix";
+    private static final String PROPNAME_INTERMEDIATE_MATRIX =
+            "android:changeTransform:intermediateMatrix";
 
     private static final String[] sTransitionProperties = {
             PROPNAME_MATRIX,
@@ -172,6 +176,10 @@
             parent.transformMatrixToGlobal(parentMatrix);
             parentMatrix.preTranslate(-parent.getScrollX(), -parent.getScrollY());
             transitionValues.values.put(PROPNAME_PARENT_MATRIX, parentMatrix);
+            transitionValues.values.put(PROPNAME_INTERMEDIATE_MATRIX,
+                    view.getTag(R.id.transitionTransform));
+            transitionValues.values.put(PROPNAME_INTERMEDIATE_PARENT_MATRIX,
+                    view.getTag(R.id.parentMatrix));
         }
         return;
     }
@@ -199,12 +207,13 @@
         ViewGroup endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
         boolean handleParentChange = mReparent && !parentsMatch(startParent, endParent);
 
-        Matrix startMatrix = (Matrix) startValues.view.getTag(R.id.transitionTransform);
+        Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_INTERMEDIATE_MATRIX);
         if (startMatrix != null) {
             startValues.values.put(PROPNAME_MATRIX, startMatrix);
         }
 
-        Matrix startParentMatrix = (Matrix) startValues.view.getTag(R.id.parentMatrix);
+        Matrix startParentMatrix = (Matrix)
+                startValues.values.get(PROPNAME_INTERMEDIATE_PARENT_MATRIX);
         if (startParentMatrix != null) {
             startValues.values.put(PROPNAME_PARENT_MATRIX, startParentMatrix);
         }
@@ -250,9 +259,11 @@
         ObjectAnimator animator = ObjectAnimator.ofObject(view, ANIMATION_MATRIX_PROPERTY,
                 new TransitionUtils.MatrixEvaluator(), startMatrix, endMatrix);
 
+        final Matrix finalEndMatrix = endMatrix;
+
         AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
             private boolean mIsCanceled;
-            private Matrix mTempMatrix;
+            private Matrix mTempMatrix = new Matrix();
 
             @Override
             public void onAnimationCancel(Animator animation) {
@@ -262,8 +273,7 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 if (!mIsCanceled) {
-                    view.setTagInternal(R.id.transitionTransform, null);
-                    view.setTagInternal(R.id.parentMatrix, null);
+                    setCurrentMatrix(finalEndMatrix);
                 }
                 ANIMATION_MATRIX_PROPERTY.set(view, null);
                 transforms.restore(view);
@@ -273,19 +283,19 @@
             public void onAnimationPause(Animator animation) {
                 ValueAnimator animator = (ValueAnimator) animation;
                 Matrix currentMatrix = (Matrix) animator.getAnimatedValue();
-                if (mTempMatrix == null) {
-                    mTempMatrix = new Matrix(currentMatrix);
-                } else {
-                    mTempMatrix.set(currentMatrix);
-                }
-                view.setTagInternal(R.id.transitionTransform, mTempMatrix);
-                transforms.restore(view);
+                setCurrentMatrix(currentMatrix);
             }
 
             @Override
             public void onAnimationResume(Animator animation) {
                 setIdentityTransforms(view);
             }
+
+            private void setCurrentMatrix(Matrix currentMatrix) {
+                mTempMatrix.set(currentMatrix);
+                view.setTagInternal(R.id.transitionTransform, mTempMatrix);
+                transforms.restore(view);
+            }
         };
 
         animator.addListener(listener);
@@ -423,6 +433,8 @@
         public void onTransitionEnd(Transition transition) {
             transition.removeListener(this);
             GhostView.removeGhost(mView);
+            mView.setTagInternal(R.id.transitionTransform, null);
+            mView.setTagInternal(R.id.parentMatrix, null);
         }
 
         @Override
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index ce3cc2f..7bd6287 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -182,11 +182,15 @@
 
         final ViewGroup sceneRoot = scene.getSceneRoot();
 
-        Transition transitionClone = transition.clone();
-        transitionClone.setSceneRoot(sceneRoot);
+        Transition transitionClone = null;
+        if (transition != null) {
+            transitionClone = transition.clone();
+            transitionClone.setSceneRoot(sceneRoot);
+        }
 
         Scene oldScene = Scene.getCurrentScene(sceneRoot);
-        if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
+        if (oldScene != null && transitionClone != null &&
+                oldScene.isCreatedFromLayoutResource()) {
             transitionClone.setCanRemoveViews(true);
         }
 
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 964b054..0701b53 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -660,8 +660,96 @@
     /** Key code constant: Voice Assist key.
      * Launches the global voice assist activity. Not delivered to applications. */
     public static final int KEYCODE_VOICE_ASSIST = 231;
+    /** Key code constant: Radio key.
+     * Toggles TV service / Radio service. */
+    public static final int KEYCODE_TV_RADIO_SERVICE = 232;
+    /** Key code constant: Teletext key.
+     * Displays Teletext service. */
+    public static final int KEYCODE_TV_TELETEXT = 233;
+    /** Key code constant: Number entry key.
+     * Initiates to enter multi-digit channel nubmber when each digit key is assigned
+     * for selecting separate channel. Corresponds to Number Entry Mode (0x1D) of CEC
+     * User Control Code. */
+    public static final int KEYCODE_TV_NUMBER_ENTRY = 234;
+    /** Key code constant: Analog Terrestrial key.
+     * Switches to analog terrestrial broadcast service. */
+    public static final int KEYCODE_TV_TERRESTRIAL_ANALOG = 235;
+    /** Key code constant: Digital Terrestrial key.
+     * Switches to digital terrestrial broadcast service. */
+    public static final int KEYCODE_TV_TERRESTRIAL_DIGITAL = 236;
+    /** Key code constant: Satellite key.
+     * Switches to digital satellite broadcast service. */
+    public static final int KEYCODE_TV_SATELLITE = 237;
+    /** Key code constant: BS key.
+     * Switches to BS digital satellite broadcasting service available in Japan. */
+    public static final int KEYCODE_TV_SATELLITE_BS = 238;
+    /** Key code constant: CS key.
+     * Switches to CS digital satellite broadcasting service available in Japan. */
+    public static final int KEYCODE_TV_SATELLITE_CS = 239;
+    /** Key code constant: BS/CS key.
+     * Toggles between BS and CS digital satellite services. */
+    public static final int KEYCODE_TV_SATELLITE_SERVICE = 240;
+    /** Key code constant: Toggle Network key.
+     * Toggles selecting broacast services. */
+    public static final int KEYCODE_TV_NETWORK = 241;
+    /** Key code constant: Antenna/Cable key.
+     * Toggles broadcast input source between antenna and cable. */
+    public static final int KEYCODE_TV_ANTENNA_CABLE = 242;
+    /** Key code constant: HDMI #1 key.
+     * Switches to HDMI input #1. */
+    public static final int KEYCODE_TV_INPUT_HDMI_1 = 243;
+    /** Key code constant: HDMI #2 key.
+     * Switches to HDMI input #2. */
+    public static final int KEYCODE_TV_INPUT_HDMI_2 = 244;
+    /** Key code constant: HDMI #3 key.
+     * Switches to HDMI input #3. */
+    public static final int KEYCODE_TV_INPUT_HDMI_3 = 245;
+    /** Key code constant: HDMI #4 key.
+     * Switches to HDMI input #4. */
+    public static final int KEYCODE_TV_INPUT_HDMI_4 = 246;
+    /** Key code constant: Composite #1 key.
+     * Switches to composite video input #1. */
+    public static final int KEYCODE_TV_INPUT_COMPOSITE_1 = 247;
+    /** Key code constant: Composite #2 key.
+     * Switches to composite video input #2. */
+    public static final int KEYCODE_TV_INPUT_COMPOSITE_2 = 248;
+    /** Key code constant: Component #1 key.
+     * Switches to component video input #1. */
+    public static final int KEYCODE_TV_INPUT_COMPONENT_1 = 249;
+    /** Key code constant: Component #2 key.
+     * Switches to component video input #2. */
+    public static final int KEYCODE_TV_INPUT_COMPONENT_2 = 250;
+    /** Key code constant: VGA #1 key.
+     * Switches to VGA (analog RGB) input #1. */
+    public static final int KEYCODE_TV_INPUT_VGA_1 = 251;
+    /** Key code constant: Audio description key.
+     * Toggles audio description off / on. */
+    public static final int KEYCODE_TV_AUDIO_DESCRIPTION = 252;
+    /** Key code constant: Audio description mixing volume up key.
+     * Louden audio description volume as compared with normal audio volume. */
+    public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253;
+    /** Key code constant: Audio description mixing volume down key.
+     * Lessen audio description volume as compared with normal audio volume. */
+    public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254;
+    /** Key code constant: Zoom mode key.
+     * Changes Zoom mode (Normal, Full, Zoom, Wide-zoom, etc.) */
+    public static final int KEYCODE_TV_ZOOM_MODE = 255;
+    /** Key code constant: Contents menu key.
+     * Goes to the title list. Corresponds to Contents Menu (0x0B) of CEC User Control
+     * Code */
+    public static final int KEYCODE_TV_CONTENTS_MENU = 256;
+    /** Key code constant: Media context menu key.
+     * Goes to the context menu of media contents. Corresponds to Media Context-sensitive
+     * Menu (0x11) of CEC User Control Code. */
+    public static final int KEYCODE_TV_MEDIA_CONTEXT_MENU = 257;
+    /** Key code constant: Timer programming key.
+     * Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of
+     * CEC User Control Code. */
+    public static final int KEYCODE_TV_TIMER_PROGRAMMING = 258;
+    /** Key code constant: Help key. */
+    public static final int KEYCODE_HELP = 259;
 
-    private static final int LAST_KEYCODE = KEYCODE_VOICE_ASSIST;
+    private static final int LAST_KEYCODE = KEYCODE_HELP;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9b1b7ed..3628355 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1726,6 +1726,34 @@
         <enum name="KEYCODE_LAST_CHANNEL" value="229" />
         <enum name="KEYCODE_TV_DATA_SERVICE" value="230" />
         <enum name="KEYCODE_VOICE_ASSIST" value="231" />
+        <enum name="KEYCODE_TV_RADIO_SERVICE" value="232" />
+        <enum name="KEYCODE_TV_TELETEXT" value="233" />
+        <enum name="KEYCODE_TV_NUMBER_ENTRY" value="234" />
+        <enum name="KEYCODE_TV_TERRESTRIAL_ANALOG" value="235" />
+        <enum name="KEYCODE_TV_TERRESTRIAL_DIGITAL" value="236" />
+        <enum name="KEYCODE_TV_SATELLITE" value="237" />
+        <enum name="KEYCODE_TV_SATELLITE_BS" value="238" />
+        <enum name="KEYCODE_TV_SATELLITE_CS" value="239" />
+        <enum name="KEYCODE_TV_SATELLITE_SERVICE" value="240" />
+        <enum name="KEYCODE_TV_NETWORK" value="241" />
+        <enum name="KEYCODE_TV_ANTENNA_CABLE" value="242" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_1" value="243" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_2" value="244" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_3" value="245" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_4" value="246" />
+        <enum name="KEYCODE_TV_INPUT_COMPOSITE_1" value="247" />
+        <enum name="KEYCODE_TV_INPUT_COMPOSITE_2" value="248" />
+        <enum name="KEYCODE_TV_INPUT_COMPONENT_1" value="249" />
+        <enum name="KEYCODE_TV_INPUT_COMPONENT_2" value="250" />
+        <enum name="KEYCODE_TV_INPUT_VGA_1" value="251" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION" value="252" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP" value="253" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN" value="254" />
+        <enum name="KEYCODE_TV_ZOOM_MODE" value="255" />
+        <enum name="KEYCODE_TV_CONTENTS_MENU" value="256" />
+        <enum name="KEYCODE_TV_MEDIA_CONTEXT_MENU" value="257" />
+        <enum name="KEYCODE_TV_TIMER_PROGRAMMING" value="258" />
+        <enum name="KEYCODE_HELP" value="259" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index a20b6d8..384226f 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -86,6 +86,8 @@
             throws XmlPullParserException, IOException {
         final TypedArray a = r.obtainAttributes(attrs, R.styleable.InsetDrawable);
         super.inflateWithAttributes(r, parser, a, R.styleable.InsetDrawable_visible);
+
+        mInsetState.mDrawable = null;
         updateStateFromTypedArray(a);
 
         // Load inner XML elements.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 2da3b27..1c6dc2c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -648,7 +648,7 @@
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
                             mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
-                                    newUserId));
+                                    newUserId, 0));
                             mSwitchingUser = false;
                         }
                     });
diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml
index c4b8794..8f25d99 100644
--- a/packages/SystemUI/res/layout/system_icons.xml
+++ b/packages/SystemUI/res/layout/system_icons.xml
@@ -36,5 +36,6 @@
     <com.android.systemui.BatteryMeterView android:id="@+id/battery"
         android:layout_height="14.5dp"
         android:layout_width="9.5dp"
+        android:layout_marginBottom="@dimen/battery_margin_bottom"
         android:layout_marginStart="7dp"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml
index 799619f..10b00eb 100644
--- a/packages/SystemUI/res/values-hdpi/dimens.xml
+++ b/packages/SystemUI/res/values-hdpi/dimens.xml
@@ -18,4 +18,11 @@
 <resources>
     <!-- Margin on the right side of the system icon group on Keyguard. -->
     <fraction name="battery_button_height_fraction">10.5%</fraction>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+         fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">20%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">12%</fraction>
+
+    <dimen name="battery_margin_bottom">1px</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml
index 7667f3e..aa85d69 100644
--- a/packages/SystemUI/res/values-mdpi/dimens.xml
+++ b/packages/SystemUI/res/values-mdpi/dimens.xml
@@ -17,4 +17,11 @@
 <resources>
     <!-- Margin on the right side of the system icon group on Keyguard. -->
     <fraction name="battery_button_height_fraction">12%</fraction>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+         fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">10%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">10%</fraction>
+
+    <dimen name="battery_margin_bottom">1px</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-tvdpi/dimens.xml b/packages/SystemUI/res/values-tvdpi/dimens.xml
index 7667f3e..5327cee 100644
--- a/packages/SystemUI/res/values-tvdpi/dimens.xml
+++ b/packages/SystemUI/res/values-tvdpi/dimens.xml
@@ -17,4 +17,11 @@
 <resources>
     <!-- Margin on the right side of the system icon group on Keyguard. -->
     <fraction name="battery_button_height_fraction">12%</fraction>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+     fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">10%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">10%</fraction>
+
+    <dimen name="battery_margin_bottom">1px</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-xhdpi/dimens.xml b/packages/SystemUI/res/values-xhdpi/dimens.xml
new file mode 100644
index 0000000..144b225
--- /dev/null
+++ b/packages/SystemUI/res/values-xhdpi/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ 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
+  -->
+
+<resources>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+         fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">25%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">12.5%</fraction>
+
+    <dimen name="battery_margin_bottom">0dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-xxhdpi/dimens.xml b/packages/SystemUI/res/values-xxhdpi/dimens.xml
new file mode 100644
index 0000000..26c8437
--- /dev/null
+++ b/packages/SystemUI/res/values-xxhdpi/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ 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
+  -->
+
+<resources>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+         fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">33%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">33%</fraction>
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 122a728..8cd4ce6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -289,13 +289,13 @@
     <dimen name="speed_bump_height">16dp</dimen>
 
     <!-- Lockscreen unlocking falsing threshold. -->
-    <dimen name="unlock_falsing_threshold">100dp</dimen>
+    <dimen name="unlock_falsing_threshold">80dp</dimen>
 
     <!-- Lockscreen falsing threshold for quick settings. -->
-    <dimen name="qs_falsing_threshold">60dp</dimen>
+    <dimen name="qs_falsing_threshold">80dp</dimen>
 
     <!-- Falsing threshold used when dismissing notifications from the lockscreen. -->
-    <dimen name="swipe_helper_falsing_threshold">100dp</dimen>
+    <dimen name="swipe_helper_falsing_threshold">70dp</dimen>
 
     <dimen name="notifications_top_padding">8dp</dimen>
     
@@ -315,7 +315,7 @@
     <dimen name="heads_up_window_height">250dp</dimen>
 
     <!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
-    <dimen name="keyguard_min_swipe_amount">85dp</dimen>
+    <dimen name="keyguard_min_swipe_amount">90dp</dimen>
 
     <!-- The minimum background radius when swiping to a side for the camera / phone affordances. -->
     <dimen name="keyguard_affordance_min_background_radius">30dp</dimen>
@@ -469,4 +469,11 @@
 
     <!-- Margin on the right side of the system icon group on Keyguard. -->
     <fraction name="battery_button_height_fraction">10.5%</fraction>
+
+    <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
+         fraction of a pixel.-->
+    <fraction name="battery_subpixel_smoothing_left">0%</fraction>
+    <fraction name="battery_subpixel_smoothing_right">0%</fraction>
+
+    <dimen name="battery_margin_bottom">0dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index d24ec66..7bdbd0a 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -46,13 +46,14 @@
 
     private static final int FULL = 96;
 
-    private static final float SUBPIXEL = 0.33f;  // inset rects for softer edges
     private static final float BOLT_LEVEL_THRESHOLD = 0.3f;  // opaque bolt below this fraction
 
     private final int[] mColors;
 
     boolean mShowPercent = true;
     private float mButtonHeightFraction;
+    private float mSubpixelSmoothingLeft;
+    private float mSubpixelSmoothingRight;
     private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
     private float mTextHeight, mWarningTextHeight;
 
@@ -208,6 +209,10 @@
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
         mButtonHeightFraction = context.getResources().getFraction(
                 R.fraction.battery_button_height_fraction, 1, 1);
+        mSubpixelSmoothingLeft = context.getResources().getFraction(
+                R.fraction.battery_subpixel_smoothing_left, 1, 1);
+        mSubpixelSmoothingRight = context.getResources().getFraction(
+                R.fraction.battery_subpixel_smoothing_right, 1, 1);
 
         mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mFramePaint.setColor(frameColor);
@@ -314,21 +319,21 @@
 
         // button-frame: area above the battery body
         mButtonFrame.set(
-                mFrame.left + width * 0.25f,
+                mFrame.left + Math.round(width * 0.25f),
                 mFrame.top,
-                mFrame.right - width * 0.25f,
+                mFrame.right - Math.round(width * 0.25f),
                 mFrame.top + buttonHeight);
 
-        mButtonFrame.top += SUBPIXEL;
-        mButtonFrame.left += SUBPIXEL;
-        mButtonFrame.right -= SUBPIXEL;
+        mButtonFrame.top += mSubpixelSmoothingLeft;
+        mButtonFrame.left += mSubpixelSmoothingLeft;
+        mButtonFrame.right -= mSubpixelSmoothingRight;
 
         // frame: battery body area
         mFrame.top += buttonHeight;
-        mFrame.left += SUBPIXEL;
-        mFrame.top += SUBPIXEL;
-        mFrame.right -= SUBPIXEL;
-        mFrame.bottom -= SUBPIXEL;
+        mFrame.left += mSubpixelSmoothingLeft;
+        mFrame.top += mSubpixelSmoothingLeft;
+        mFrame.right -= mSubpixelSmoothingRight;
+        mFrame.bottom -= mSubpixelSmoothingRight;
 
         // set the battery charging color
         mBatteryPaint.setColor(tracker.plugged ? mChargeColor : getColorForLevel(level));
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 54c2c09..f8d0d9e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.UserInfo;
 import android.media.AudioManager;
 import android.media.SoundPool;
 import android.os.Bundle;
@@ -302,6 +303,13 @@
         @Override
         public void onUserSwitchComplete(int userId) {
             mSwitchingUser = false;
+            if (userId != UserHandle.USER_OWNER) {
+                UserInfo info = UserManager.get(mContext).getUserInfo(userId);
+                if (info != null && info.isGuest()) {
+                    // If we just switched to a guest, try to dismiss keyguard.
+                    dismiss();
+                }
+            }
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 6cae7d4..082dde6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -355,6 +355,8 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        // For the non-primary user, ensure that the SystemSericesProxy is initialized
+        RecentsTaskLoader.initialize(this);
 
         // Initialize the loader and the configuration
         mConfig = RecentsConfiguration.reinitialize(this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ce29407..37bc7c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1281,7 +1281,9 @@
             // Add a basic notification template
             publicViewLocal = LayoutInflater.from(mContext).inflate(
                     com.android.internal.R.layout.notification_template_material_base,
-                    expandedPublic, true);
+                    expandedPublic, false);
+            publicViewLocal.setIsRootNamespace(true);
+            expandedPublic.setContractedChild(publicViewLocal);
 
             final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title);
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index dfcc408..e3a0b18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -17,10 +17,15 @@
 package com.android.systemui.statusbar;
 
 import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 
+import android.widget.ImageView;
 import com.android.systemui.R;
 
 public class ExpandableNotificationRow extends ActivatableNotificationView {
@@ -62,6 +67,51 @@
     private boolean mWasReset;
     private NotificationGuts mGuts;
 
+    public void setIconAnimationRunning(boolean running) {
+        setIconAnimationRunning(running, mPublicLayout);
+        setIconAnimationRunning(running, mPrivateLayout);
+    }
+
+    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
+        if (layout != null) {
+            View contractedChild = layout.getContractedChild();
+            View expandedChild = layout.getExpandedChild();
+            setIconAnimationRunningForChild(running, contractedChild);
+            setIconAnimationRunningForChild(running, expandedChild);
+        }
+    }
+
+    private void setIconAnimationRunningForChild(boolean running, View child) {
+        if (child != null) {
+            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
+            setIconRunning(icon, running);
+            ImageView rightIcon = (ImageView) child.findViewById(
+                    com.android.internal.R.id.right_icon);
+            setIconRunning(rightIcon, running);
+        }
+    }
+
+    private void setIconRunning(ImageView imageView, boolean running) {
+        if (imageView != null) {
+            Drawable drawable = imageView.getDrawable();
+            if (drawable instanceof AnimationDrawable) {
+                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
+                if (running) {
+                    animationDrawable.start();
+                } else {
+                    animationDrawable.stop();
+                }
+            } else if (drawable instanceof AnimatedVectorDrawable) {
+                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
+                if (running) {
+                    animationDrawable.start();
+                } else {
+                    animationDrawable.stop();
+                }
+            }
+        }
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 5878ae1..a4161f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -251,15 +251,19 @@
     }
 
     public void setCircleRadius(float circleRadius) {
-        setCircleRadius(circleRadius, false);
+        setCircleRadius(circleRadius, false, false);
+    }
+
+    public void setCircleRadius(float circleRadius, boolean slowAnimation) {
+        setCircleRadius(circleRadius, slowAnimation, false);
     }
 
     public void setCircleRadiusWithoutAnimation(float circleRadius) {
         cancelAnimator(mCircleAnimator);
-        setCircleRadius(circleRadius, true);
+        setCircleRadius(circleRadius, false ,true);
     }
 
-    private void setCircleRadius(float circleRadius, boolean noAnimation) {
+    private void setCircleRadius(float circleRadius, boolean slowAnimation, boolean noAnimation) {
 
         // Check if we need a new animation
         boolean radiusHidden = (mCircleAnimator != null && mCircleWillBeHidden)
@@ -292,10 +296,13 @@
                     ? mDisappearInterpolator
                     : mAppearInterpolator;
             animator.setInterpolator(interpolator);
-            float durationFactor = Math.abs(mCircleRadius - circleRadius)
-                    / (float) mMinBackgroundRadius;
-            long duration = (long) (CIRCLE_APPEAR_DURATION * durationFactor);
-            duration = Math.min(duration, CIRCLE_DISAPPEAR_MAX_DURATION);
+            long duration = 250;
+            if (!slowAnimation) {
+                float durationFactor = Math.abs(mCircleRadius - circleRadius)
+                        / (float) mMinBackgroundRadius;
+                duration = (long) (CIRCLE_APPEAR_DURATION * durationFactor);
+                duration = Math.min(duration, CIRCLE_DISAPPEAR_MAX_DURATION);
+            }
             animator.setDuration(duration);
             animator.start();
             if (mPreviewView != null && mPreviewView.getVisibility() == View.VISIBLE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 8b4c2c4..e31eb7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -88,6 +88,14 @@
         mContractedVisible = true;
     }
 
+    public View getContractedChild() {
+        return mContractedChild;
+    }
+
+    public View getExpandedChild() {
+        return mExpandedChild;
+    }
+
     public void setContractedChild(View child) {
         if (mContractedChild != null) {
             mContractedChild.animate().cancel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index eca8e6a..a9c701a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -20,8 +20,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.os.PowerManager;
-import android.os.SystemClock;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -85,9 +83,9 @@
         mContext = context;
         mCallback = callback;
         initIcons();
-        updateIcon(mLeftIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
-        updateIcon(mCenterIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
-        updateIcon(mRightIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+        updateIcon(mLeftIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false, false);
+        updateIcon(mCenterIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false, false);
+        updateIcon(mRightIcon, 0.0f, SWIPE_RESTING_ALPHA_AMOUNT, false, false);
         initDimens();
     }
 
@@ -295,8 +293,7 @@
         float vel = getCurrentVelocity();
 
         // We snap back if the current translation is not far enough
-        boolean snapBack = Math.abs(mTranslation) < Math.abs(mTranslationOnDown)
-                + mMinTranslationAmount;
+        boolean snapBack = isBelowFalsingThreshold();
 
         // or if the velocity is in the opposite direction.
         boolean velIsInWrongDirection = vel * mTranslation < 0;
@@ -305,6 +302,11 @@
         fling(vel, snapBack || forceSnapBack);
     }
 
+    private boolean isBelowFalsingThreshold() {
+        return Math.abs(mTranslation) < Math.abs(mTranslationOnDown)
+                + mMinTranslationAmount;
+    }
+
     private void fling(float vel, final boolean snapBack) {
         float target = mTranslation < 0 ? -mCallback.getPageWidth() : mCallback.getPageWidth();
         target = snapBack ? 0 : target;
@@ -355,13 +357,14 @@
 
             boolean animateIcons = isReset && animateReset;
             float radius = getRadiusFromTranslation(absTranslation);
+            boolean slowAnimation = isReset && isBelowFalsingThreshold();
             if (!isReset) {
-                updateIcon(targetView, radius, alpha, false);
+                updateIcon(targetView, radius, alpha, false, false);
             } else {
-                updateIcon(targetView, 0.0f, fadeOutAlpha, animateIcons);
+                updateIcon(targetView, 0.0f, fadeOutAlpha, animateIcons, slowAnimation);
             }
-            updateIcon(otherView, 0.0f, fadeOutAlpha, animateIcons);
-            updateIcon(mCenterIcon, 0.0f, fadeOutAlpha, animateIcons);
+            updateIcon(otherView, 0.0f, fadeOutAlpha, animateIcons, slowAnimation);
+            updateIcon(mCenterIcon, 0.0f, fadeOutAlpha, animateIcons, slowAnimation);
 
             mTranslation = translation;
         }
@@ -392,16 +395,16 @@
     }
 
     public void animateHideLeftRightIcon() {
-        updateIcon(mRightIcon, 0f, 0f, true);
-        updateIcon(mLeftIcon, 0f, 0f, true);
+        updateIcon(mRightIcon, 0f, 0f, true, false);
+        updateIcon(mLeftIcon, 0f, 0f, true, false);
     }
 
     private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha,
-            boolean animate) {
+            boolean animate, boolean slowRadiusAnimation) {
         if (view.getVisibility() != View.VISIBLE) {
             return;
         }
-        view.setCircleRadius(circleRadius);
+        view.setCircleRadius(circleRadius, slowRadiusAnimation);
         updateIconAlpha(view, alpha, animate);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 91a8b22..bae1864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -548,7 +548,7 @@
     }
 
     private boolean flingExpandsQs(float vel) {
-        if (!mQsTouchAboveFalsingThreshold && mStatusBarState == StatusBarState.KEYGUARD) {
+        if (isBelowFalsingThreshold()) {
             return false;
         }
         if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -558,6 +558,10 @@
         }
     }
 
+    private boolean isBelowFalsingThreshold() {
+        return !mQsTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded();
+    }
+
     private float getQsExpansionFraction() {
         return Math.min(1f, (mQsExpansionHeight - mQsMinExpansionHeight)
                 / (getTempQsMaxExpansion() - mQsMinExpansionHeight));
@@ -1122,9 +1126,16 @@
             }
             return;
         }
+        boolean belowFalsingThreshold = isBelowFalsingThreshold();
+        if (belowFalsingThreshold) {
+            vel = 0;
+        }
         mScrollView.setBlockFlinging(true);
         ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
         mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel);
+        if (belowFalsingThreshold) {
+            animator.setDuration(350);
+        }
         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
@@ -1692,9 +1703,9 @@
     }
 
     public void setEmptyDragAmount(float amount) {
-        float factor = 1f;
+        float factor = 0.8f;
         if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
-            factor = 0.6f;
+            factor = 0.4f;
         } else if (!mStatusBar.hasActiveNotifications()) {
             factor = 0.4f;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 6127811..7261ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -479,7 +479,7 @@
      * @return whether a fling should expands the panel; contracts otherwise
      */
     protected boolean flingExpands(float vel, float vectorVel) {
-        if (!mTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded()) {
+        if (isBelowFalsingThreshold()) {
             return true;
         }
         if (Math.abs(vectorVel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -489,6 +489,10 @@
         }
     }
 
+    private boolean isBelowFalsingThreshold() {
+        return !mTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded();
+    }
+
     protected void fling(float vel, boolean expand) {
         cancelPeek();
         float target = expand ? getMaxPanelHeight() : 0.0f;
@@ -509,7 +513,14 @@
         mOverExpandedBeforeFling = getOverExpansionAmount() > 0f;
         ValueAnimator animator = createHeightAnimator(target);
         if (expand) {
+            boolean belowFalsingThreshold = isBelowFalsingThreshold();
+            if (belowFalsingThreshold) {
+                vel = 0;
+            }
             mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight());
+            if (belowFalsingThreshold) {
+                animator.setDuration(350);
+            }
         } else {
             mFlingAnimationUtils.applyDismissing(animator, mExpandedHeight, target, vel,
                     getHeight());
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 148b00c..fed579c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1467,6 +1467,7 @@
             // drawn when removed
             getOverlay().add(child);
         }
+        updateAnimationState(false, child);
 
         // Make sure the clipRect we might have set is removed
         child.setClipBounds(null);
@@ -1545,10 +1546,28 @@
         mStackScrollAlgorithm.notifyChildrenChanged(this);
         ((ExpandableView) child).setOnHeightChangedListener(this);
         generateAddAnimation(child, false /* fromMoreCard */);
+        updateAnimationState(mAnimationsEnabled && mIsExpanded, child);
     }
 
     public void setAnimationsEnabled(boolean animationsEnabled) {
         mAnimationsEnabled = animationsEnabled;
+        updateNotificationAnimationStates();
+    }
+
+    private void updateNotificationAnimationStates() {
+        boolean running = mIsExpanded && mAnimationsEnabled;
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            updateAnimationState(running, child);
+        }
+    }
+
+    private void updateAnimationState(boolean running, View child) {
+        if (child instanceof ExpandableNotificationRow) {
+            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+            row.setIconAnimationRunning(running);
+        }
     }
 
     public boolean isAddOrRemoveAnimationPending() {
@@ -1918,8 +1937,12 @@
     }
 
     private void setIsExpanded(boolean isExpanded) {
+        boolean changed = isExpanded != mIsExpanded;
         mIsExpanded = isExpanded;
         mStackScrollAlgorithm.setIsExpanded(isExpanded);
+        if (changed) {
+            updateNotificationAnimationStates();
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6bc1c9c..780efa1 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1262,7 +1262,7 @@
         if (err == ActivityManager.START_SUCCESS) {
             final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
-                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
+                    + "} from uid " + callingUid
                     + " on display " + (container == null ? (mFocusedStack == null ?
                             Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
                             (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
@@ -2075,6 +2075,7 @@
             }
             targetStack = inTask.stack;
             targetStack.moveTaskToFrontLocked(inTask, r, options);
+            targetStack.moveToFront();
             mWindowManager.moveTaskToTop(inTask.taskId);
 
             // Check whether we should actually launch the new activity in to the task,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 564a3df..cad2772 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -40,7 +40,6 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
@@ -70,7 +69,6 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.security.Credentials;
-import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
 import android.util.Log;
@@ -2749,7 +2747,8 @@
         return !"".equals(state);
     }
 
-    public boolean installCaCert(ComponentName who, byte[] certBuffer) throws RemoteException {
+    @Override
+    public void enforceCanManageCaCerts(ComponentName who) {
         if (who == null) {
             mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
         } else {
@@ -2757,6 +2756,11 @@
                 getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             }
         }
+    }
+
+    @Override
+    public boolean installCaCert(ComponentName admin, byte[] certBuffer) throws RemoteException {
+        enforceCanManageCaCerts(admin);
 
         byte[] pemCert;
         try {
@@ -2791,21 +2795,15 @@
         return false;
     }
 
-    private static X509Certificate parseCert(byte[] certBuffer)
-            throws CertificateException, IOException {
+    private static X509Certificate parseCert(byte[] certBuffer) throws CertificateException {
         CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
         return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
                 certBuffer));
     }
 
-    public void uninstallCaCert(ComponentName who, String alias) {
-        if (who == null) {
-            mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
-        } else {
-            synchronized (this) {
-                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            }
-        }
+    @Override
+    public void uninstallCaCert(ComponentName admin, String alias) {
+        enforceCanManageCaCerts(admin);
 
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
         final long id = Binder.clearCallingIdentity();