Merge "Fix intent tile to unlock on launching activities" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index dea5255..a0dccd5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15863,6 +15863,10 @@
     ctor public MediaDrmException(java.lang.String);
   }
 
+  public class MediaDrmResetException extends java.lang.IllegalStateException {
+    ctor public MediaDrmResetException(java.lang.String);
+  }
+
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
@@ -34575,6 +34579,7 @@
     method public abstract void invalidate();
     method public void invalidateContentRect();
     method public boolean isTitleOptional();
+    method public void onWindowFocusChanged(boolean);
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
     method public abstract void setSubtitle(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index d0225e1..7e3e051 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -17118,6 +17118,10 @@
     ctor public MediaDrmException(java.lang.String);
   }
 
+  public class MediaDrmResetException extends java.lang.IllegalStateException {
+    ctor public MediaDrmResetException(java.lang.String);
+  }
+
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
@@ -36856,6 +36860,7 @@
     method public abstract void invalidate();
     method public void invalidateContentRect();
     method public boolean isTitleOptional();
+    method public void onWindowFocusChanged(boolean);
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
     method public abstract void setSubtitle(int);
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 1461380..e178087 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -35,6 +35,9 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.TransactionTooLargeException;
+import android.util.Log;
+
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.content.ReferrerIntent;
 
@@ -921,8 +924,13 @@
         info.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
         data.writeInt(processState);
-        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
-                IBinder.FLAG_ONEWAY);
+        try {
+            mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
+                    IBinder.FLAG_ONEWAY);
+        } catch (TransactionTooLargeException e) {
+            Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
+            throw e;
+        }
         data.recycle();
     }
 
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 08c5236..d83dfc5 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1480,7 +1480,11 @@
      * Write the contents of the IntentFilter as an XML stream.
      */
     public void writeToXml(XmlSerializer serializer) throws IOException {
-        serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(getAutoVerify()));
+
+        if (getAutoVerify()) {
+            serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(true));
+        }
+
         int N = countActions();
         for (int i=0; i<N; i++) {
             serializer.startTag(null, ACTION_STR);
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index f8db6d9..c656fb8 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -667,7 +667,7 @@
      * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }.
      * The fps range can be controlled via {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}.</p>
      * <p>In this capability, the camera device will override aeMode, awbMode, and afMode to
-     * ON, ON, and CONTINUOUS_VIDEO, respectively. All post-processing block mode
+     * ON, AUTO, and CONTINUOUS_VIDEO, respectively. All post-processing block mode
      * controls will be overridden to be FAST. Therefore, no manual control of capture
      * and post-processing parameters is possible. All other controls operate the
      * same as when {@link CaptureRequest#CONTROL_MODE android.control.mode} == AUTO. This means that all other
@@ -1666,9 +1666,9 @@
      * <p>Enabling this disables control.aeMode, control.awbMode and
      * control.afMode controls; the camera device will ignore
      * those settings while USE_SCENE_MODE is active (except for
-     * FACE_PRIORITY scene mode). Other control entries are still
-     * active.  This setting can only be used if scene mode is
-     * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
+     * FACE_PRIORITY scene mode). Other control entries are still active.
+     * This setting can only be used if scene mode is supported (i.e.
+     * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
      * contain some modes other than DISABLED).</p>
      *
      * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
@@ -1940,6 +1940,40 @@
      */
     public static final int CONTROL_SCENE_MODE_HDR = 18;
 
+    /**
+     * <p>Same as FACE_PRIORITY scene mode, except that the camera
+     * device will choose higher sensivity values ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity})
+     * under low light conditions.</p>
+     * <p>The camera device may be tuned to expose the images in a reduced
+     * sensitivity range to produce the best quality images. For example,
+     * if the {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} gives range of [100, 1600],
+     * the camera device auto-exposure routine tuning process may limit the actual
+     * exposure sensivity range to [100, 1200] to ensure that the noise level isn't
+     * exessive to compromise the image quality. Under this situation, the image under
+     * low light may be under-exposed when the sensor max exposure time (bounded by the
+     * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of the
+     * ON_* modes) and effecitve max sensitivity are reached. This scene mode allows the
+     * camera device auto-exposure routine to increase the sensitivity up to the max
+     * sensitivity specified by {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} when the scene is too
+     * dark and the max exposure time is reached. The captured images may be noisier
+     * compared with the images captured in normal FACE_PRIORITY mode, therefore, it is
+     * recommended that the application only use this scene mode when it is capable of
+     * reducing the noise level of the captured images.</p>
+     * <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+     * remain active when FACE_PRIORITY_LOW_LIGHT is set.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     * @hide
+     */
+    public static final int CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19;
+
     //
     // Enumeration values for CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
     //
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index bc625dd..9fa6687 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1448,9 +1448,9 @@
      * <p>Scene modes are custom camera modes optimized for a certain set of conditions and
      * capture settings.</p>
      * <p>This is the mode that that is active when
-     * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
-     * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
-     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+     * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will
+     * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+     * while in use.</p>
      * <p>The interpretation and implementation of these scene modes is left
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index da216aa..b1fb615 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1960,9 +1960,9 @@
      * <p>Scene modes are custom camera modes optimized for a certain set of conditions and
      * capture settings.</p>
      * <p>This is the mode that that is active when
-     * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
-     * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
-     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+     * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will
+     * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+     * while in use.</p>
      * <p>The interpretation and implementation of these scene modes is left
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index dbb5146..f9c50f3 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -635,8 +635,8 @@
             if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
                 argsForZygote.add("--enable-jit");
             }
-            if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) {
-                argsForZygote.add("--generate-cfi");
+            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
+                argsForZygote.add("--generate-debug-info");
             }
             if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                 argsForZygote.add("--enable-assert");
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index e4fab12..62c28ac 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -191,8 +191,9 @@
     public static final int KM_ERROR_MISSING_NONCE = -51;
     public static final int KM_ERROR_INVALID_NONCE = -52;
     public static final int KM_ERROR_MISSING_MAC_LENGTH = -53;
-    public static final int KM_ERROR_RESCOPABLE_KEY_NOT_USABLE = -54;
+    public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54;
     public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55;
+    public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 8c6cd09..0309d24 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -41,6 +41,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -463,15 +464,28 @@
             ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
                     .getActiveNotificationsFromListener(mWrapper, keys, trim);
             List<StatusBarNotification> list = parceledList.getList();
-
+            ArrayList<StatusBarNotification> corruptNotifications = null;
             int N = list.size();
             for (int i = 0; i < N; i++) {
-                Notification notification = list.get(i).getNotification();
-                Builder.rebuild(getContext(), notification);
-                // convert icon metadata to legacy format for older clients
-                createLegacyIconExtras(notification);
+                StatusBarNotification sbn = list.get(i);
+                Notification notification = sbn.getNotification();
+                try {
+                    Builder.rebuild(getContext(), notification);
+                    // convert icon metadata to legacy format for older clients
+                    createLegacyIconExtras(notification);
+                } catch (IllegalArgumentException e) {
+                    if (corruptNotifications == null) {
+                        corruptNotifications = new ArrayList<>(N);
+                    }
+                    corruptNotifications.add(sbn);
+                    Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
+                            sbn.getPackageName());
+                }
             }
-            return list.toArray(new StatusBarNotification[N]);
+            if (corruptNotifications != null) {
+                list.removeAll(corruptNotifications);
+            }
+            return list.toArray(new StatusBarNotification[list.size()]);
         } catch (android.os.RemoteException ex) {
             Log.v(TAG, "Unable to contact notification manager", ex);
         }
@@ -671,16 +685,28 @@
                 Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
                 return;
             }
-            Notification.Builder.rebuild(getContext(), sbn.getNotification());
 
-            // convert icon metadata to legacy format for older clients
-            createLegacyIconExtras(sbn.getNotification());
+            try {
+                Notification.Builder.rebuild(getContext(), sbn.getNotification());
+                // convert icon metadata to legacy format for older clients
+                createLegacyIconExtras(sbn.getNotification());
+            } catch (IllegalArgumentException e) {
+                // drop corrupt notification
+                sbn = null;
+                Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
+                        sbn.getPackageName());
+            }
 
             // protect subclass from concurrent modifications of (@link mNotificationKeys}.
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
+                    if (sbn != null) {
+                        NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
+                    } else {
+                        // still pass along the ranking map, it may contain other information
+                        NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
+                    }
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationPosted", t);
                 }
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index 80dcecc..ea979c8 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -261,6 +261,16 @@
     public abstract MenuInflater getMenuInflater();
 
     /**
+     * Called when the window containing the view that started this action mode gains or loses
+     * focus.
+     *
+     * @param hasWindowFocus True if the window containing the view that started this action mode
+     *        now has focus, false otherwise.
+     *
+     */
+    public void onWindowFocusChanged(boolean hasWindowFocus) {}
+
+    /**
      * Returns whether the UI presenting this action mode can take focus or not.
      * This is used by internal components within the framework that would otherwise
      * present an action mode UI that requires focus, such as an EditText as a custom view.
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 339038e..affc5da 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@
         View baselineView = null;
         LayoutParams baselineParams = null;
         for (int i = 0; i < count; i++) {
-            final View child = views[i];
+            final View child = getChildAt(i);
             if (child.getVisibility() != GONE) {
                 final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
                 if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@
 
             if (offsetHorizontalAxis) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                         final int[] rules = params.getRules(layoutDirection);
                         if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
                             centerHorizontal(child, params, width);
@@ -578,9 +578,9 @@
 
             if (offsetVerticalAxis) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                         final int[] rules = params.getRules(layoutDirection);
                         if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
                             centerVertical(child, params, height);
@@ -607,9 +607,9 @@
             final int verticalOffset = contentBounds.top - top;
             if (horizontalOffset != 0 || verticalOffset != 0) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE && child != ignore) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                         if (horizontalGravity) {
                             params.mLeft += horizontalOffset;
                             params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@
         if (isLayoutRtl()) {
             final int offsetWidth = myWidth - width;
             for (int i = 0; i < count; i++) {
-                final View child = views[i];
+                View child = getChildAt(i);
                 if (child.getVisibility() != GONE) {
-                    final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                    LayoutParams params = (LayoutParams) child.getLayoutParams();
                     params.mLeft -= offsetWidth;
                     params.mRight -= offsetWidth;
                 }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 4f6d781..c97fdf4 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -41,8 +41,8 @@
     public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
     /** enable the JIT compiler */
     public static final int DEBUG_ENABLE_JIT         = 1 << 5;
-    /** Force generation of CFI code */
-    public static final int DEBUG_GENERATE_CFI       = 1 << 6;
+    /** Force generation of native debugging information. */
+    public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 6;
 
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = 0;
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 1a0345b..fa870b9 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -322,7 +322,7 @@
 
         /**
          * From --enable-debugger, --enable-checkjni, --enable-assert,
-         * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging.
+         * --enable-safemode, --enable-jit, --generate-debug-info and --enable-jni-logging.
          */
         int debugFlags;
 
@@ -434,8 +434,8 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
                 } else if (arg.equals("--enable-jit")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
-                } else if (arg.equals("--generate-cfi")) {
-                    debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+                } else if (arg.equals("--generate-debug-info")) {
+                    debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
                 } else if (arg.equals("--enable-jni-logging")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
                 } else if (arg.equals("--enable-assert")) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 66f6079..15ed5bd 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3223,12 +3223,11 @@
                 cb.onWindowFocusChanged(hasWindowFocus);
             }
 
-            if (mFloatingToolbar != null) {
-                if (hasWindowFocus) {
-                    mFloatingToolbar.show();
-                } else {
-                    mFloatingToolbar.dismiss();
-                }
+            if (mPrimaryActionMode != null) {
+                mPrimaryActionMode.onWindowFocusChanged(hasWindowFocus);
+            }
+            if (mFloatingActionMode != null) {
+                mFloatingActionMode.onWindowFocusChanged(hasWindowFocus);
             }
         }
 
@@ -3441,8 +3440,7 @@
             mFloatingActionMode = mode;
             mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this);
             ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar);
-            mFloatingActionMode.invalidate();
-            mFloatingToolbar.show();
+            mFloatingActionMode.invalidate();  // Will show the floating toolbar if necessary.
             mFloatingActionModeOriginatingView.getViewTreeObserver()
                 .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
         }
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 784b256..863506b 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -197,6 +197,13 @@
     }
 
     @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        checkToolbarInitialized();
+        mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus);
+        mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
+    }
+
+    @Override
     public void finish() {
         checkToolbarInitialized();
         reset();
@@ -237,6 +244,7 @@
     }
 
     private void reset() {
+        mFloatingToolbar.dismiss();
         mFloatingToolbarVisibilityHelper.deactivate();
         mOriginatingView.removeCallbacks(mMovingOff);
         mOriginatingView.removeCallbacks(mHideOff);
@@ -253,6 +261,7 @@
         private boolean mHideRequested;
         private boolean mMoving;
         private boolean mOutOfBounds;
+        private boolean mWindowFocused = true;
 
         private boolean mActive;
 
@@ -264,6 +273,7 @@
             mHideRequested = false;
             mMoving = false;
             mOutOfBounds = false;
+            mWindowFocused = true;
 
             mActive = true;
         }
@@ -285,12 +295,16 @@
             mOutOfBounds = outOfBounds;
         }
 
+        public void setWindowFocused(boolean windowFocused) {
+            mWindowFocused = windowFocused;
+        }
+
         public void updateToolbarVisibility() {
             if (!mActive) {
                 return;
             }
 
-            if (mHideRequested || mMoving || mOutOfBounds) {
+            if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) {
                 mToolbar.hide();
             } else {
                 mToolbar.show();
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 65f2f53f..523663c 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -546,25 +546,25 @@
         private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
             refreshViewPort();
 
-            int availableHeightAboveContent =
-                    contentRect.top - mViewPort.top - 2 * mMarginVertical;
-            int availableHeightBelowContent =
-                    mViewPort.bottom - contentRect.bottom - 2 * mMarginVertical;
-            int availableHeightThroughContent =
-                    mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
-
             int x = contentRect.centerX() - getWidth() / 2;
             // Update x so that the toolbar isn't rendered behind the nav bar in landscape.
             x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
 
             int y;
+
+            int availableHeightAboveContent = contentRect.top - mViewPort.top;
+            int availableHeightBelowContent = mViewPort.bottom - contentRect.bottom;
+
             if (mOverflowPanel == null) {  // There is no overflow.
-                if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()) {
+                if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()) {
                     // There is enough space at the top of the content.
                     y = contentRect.top - getToolbarHeightWithVerticalMargin();
-                } else if (availableHeightBelowContent > getToolbarHeightWithVerticalMargin()) {
+                } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
                     // There is enough space at the bottom of the content.
                     y = contentRect.bottom;
+                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) {
+                    // Just enough space to fit the toolbar with no vertical margins.
+                    y = contentRect.bottom - mMarginVertical;
                 } else {
                     // Not enough space. Prefer to position as high as possible.
                     y = Math.max(
@@ -572,32 +572,47 @@
                             contentRect.top - getToolbarHeightWithVerticalMargin());
                 }
             } else {  // There is an overflow.
-                if (availableHeightAboveContent > mOverflowPanel.getMinimumHeight()) {
+                int margin = 2 * mMarginVertical;
+                int minimumOverflowHeightWithMargin = mOverflowPanel.getMinimumHeight() + margin;
+                int availableHeightThroughContentDown =
+                        mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
+                int availableHeightThroughContentUp =
+                        contentRect.bottom - mViewPort.top + getToolbarHeightWithVerticalMargin();
+
+                if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the top of the content rect for the overflow.
                     // Position above and open upwards.
-                    updateOverflowHeight(availableHeightAboveContent);
+                    updateOverflowHeight(availableHeightAboveContent - margin);
                     y = contentRect.top - getHeight();
                     mOverflowDirection = OVERFLOW_DIRECTION_UP;
-                } else if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()
-                        && availableHeightThroughContent > mOverflowPanel.getMinimumHeight()) {
+                } else if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()
+                        && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the top of the content rect for the main panel
                     // but not the overflow.
                     // Position above but open downwards.
-                    updateOverflowHeight(availableHeightThroughContent);
+                    updateOverflowHeight(availableHeightThroughContentDown - margin);
                     y = contentRect.top - getToolbarHeightWithVerticalMargin();
                     mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
-                } else if (availableHeightBelowContent > mOverflowPanel.getMinimumHeight()) {
+                } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the bottom of the content rect for the overflow.
                     // Position below and open downwards.
-                    updateOverflowHeight(availableHeightBelowContent);
+                    updateOverflowHeight(availableHeightBelowContent - margin);
                     y = contentRect.bottom;
                     mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
+                } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()
+                        && mViewPort.height() >= minimumOverflowHeightWithMargin) {
+                    // There is enough space at the bottom of the content rect for the main panel
+                    // but not the overflow.
+                    // Position below but open upwards.
+                    updateOverflowHeight(availableHeightThroughContentUp - margin);
+                    y = contentRect.bottom + getToolbarHeightWithVerticalMargin() - getHeight();
+                    mOverflowDirection = OVERFLOW_DIRECTION_UP;
                 } else {
                     // Not enough space.
-                    // Position at the bottom of the view port and open upwards.
-                    updateOverflowHeight(mViewPort.height());
-                    y = mViewPort.bottom - getHeight();
-                    mOverflowDirection = OVERFLOW_DIRECTION_UP;
+                    // Position at the top of the view port and open downwards.
+                    updateOverflowHeight(mViewPort.height() - margin);
+                    y = mViewPort.top;
+                    mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
                 }
                 mOverflowPanel.setOverflowDirection(mOverflowDirection);
             }
@@ -1422,7 +1437,6 @@
         PopupWindow popupWindow = new PopupWindow(popupContentHolder);
         popupWindow.setWindowLayoutType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
-        popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
         popupWindow.setAnimationStyle(0);
         popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         content.setLayoutParams(new ViewGroup.LayoutParams(
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7c2b28d..2c35a8b 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -876,16 +876,16 @@
                        "-Xzygote-max-boot-retry=");
 
     /*
-     * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot
-     * image, if it is compiled on device, will include CFI info, as well as other compilations
-     * started by the runtime.
+     * When running with debug.generate-debug-info, add --generate-debug-info to
+     * the compiler options so that the boot image, if it is compiled on device,
+     * will include native debugging information.
      */
-    property_get("debug.gencfi", propBuf, "");
+    property_get("debug.generate-debug-info", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
         addOption("-Xcompiler-option");
-        addOption("--include-cfi");
+        addOption("--generate-debug-info");
         addOption("-Ximage-compiler-option");
-        addOption("--include-cfi");
+        addOption("--generate-debug-info");
     }
 
     initArgs.version = JNI_VERSION_1_4;
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 9acfee2..ab61e2b 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -89,10 +89,23 @@
  * encrypted content, the samples returned from the extractor remain encrypted, they
  * are only decrypted when the samples are delivered to the decoder.
  * <p>
- * MediaDrm methods throw {@link java.lang.IllegalStateException}
- * when a method is called on a MediaDrm object that is in an invalid or inoperable
- * state. This is typically due to incorrect application API usage, but may also
- * be due to an unrecoverable failure in the DRM plugin or security hardware.
+ * MediaDrm methods throw {@link android.media.MediaDrm.MediaDrmStateException}
+ * when a method is called on a MediaDrm object that has had an unrecoverable failure 
+ * in the DRM plugin or security hardware. 
+ * {@link android.media.MediaDrm.MediaDrmStateException} extends 
+ * {@link java.lang.IllegalStateException} with the addition of a developer-readable 
+ * diagnostic information string associated with the exception.
+ * <p>
+ * In the event of a mediaserver process crash or restart while a MediaDrm object
+ * is active, MediaDrm methods may throw {@link android.media.MediaDrmResetException}.
+ * To recover, the app must release the MediaDrm object, then create and initialize
+ * a new one.
+ * <p>
+ * As {@link android.media.MediaDrmResetException} and 
+ * {@link android.media.MediaDrm.MediaDrmStateException} both extend 
+ * {@link java.lang.IllegalStateException}, they should be in an earlier catch() 
+ * block than {@link java.lang.IllegalStateException} if handled separately.
+ * <p>
  * <a name="Callbacks"></a>
  * <h3>Callbacks</h3>
  * <p>Applications should register for informational events in order
diff --git a/media/java/android/media/MediaDrmResetException.java b/media/java/android/media/MediaDrmResetException.java
new file mode 100644
index 0000000..3b2da1e
--- /dev/null
+++ b/media/java/android/media/MediaDrmResetException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 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 android.media;
+
+/**
+ * This exception is thrown when the MediaDrm instance has become unusable
+ * due to a restart of the mediaserver process.  To continue, the app must
+ * release the MediaDrm object, then create and initialize a new one.
+ */
+public class MediaDrmResetException extends IllegalStateException {
+    public MediaDrmResetException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index d456dc10..9ec0312 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -308,6 +308,10 @@
     } else if (err == ERROR_DRM_DEVICE_REVOKED) {
         jniThrowException(env, "android/media/DeniedByServerException", msg);
         return true;
+    } else if (err == DEAD_OBJECT) {
+        jniThrowException(env, "android/media/MediaDrmResetException",
+                "mediaserver died");
+        return true;
     } else if (err != OK) {
         String8 errbuf;
         if (drmMessage != NULL) {
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index fdc586b..aba4bbe 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -472,6 +472,8 @@
 
     if (lpJniStorage) {
         ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
+        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
+        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);
         delete lpJniStorage;
     }
 }
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 6098b4a..0557019 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -450,6 +450,8 @@
 
     if (lpJniStorage) {
         ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
+        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_class);
+        env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_ref);
         delete lpJniStorage;
     }
 }
diff --git a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml b/packages/SystemUI/res/drawable/managed_profile_toast_background.xml
deleted file mode 100644
index 5c77b9a..0000000
--- a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <corners android:radius="2dp" />
-    <solid android:color="@color/managed_profile_toast_background" />
-</shape>
diff --git a/packages/SystemUI/res/layout/managed_profile_toast.xml b/packages/SystemUI/res/layout/managed_profile_toast.xml
deleted file mode 100644
index 5a01ca7..0000000
--- a/packages/SystemUI/res/layout/managed_profile_toast.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2015 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:paddingLeft="32dp"
-        android:paddingRight="32dp"
-        android:background="@drawable/managed_profile_toast_background">
-    <ImageView
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="16dp"
-            android:src="@drawable/stat_sys_managed_profile_status"/>
-    <TextView android:text="@string/managed_profile_foreground_toast"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textColor="@android:color/white"
-            android:textSize="14sp"
-            android:layout_gravity="center_horizontal" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 9a96939..0dcbe88 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -143,6 +143,4 @@
     <color name="volume_icon_color">#ffffffff</color>
     <color name="volume_settings_icon_color">#7fffffff</color>
     <color name="volume_slider_inactive">#FFB0BEC5</color><!-- blue grey 200 -->
-
-    <color name="managed_profile_toast_background">#E5000000</color><!-- 90% black -->
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b0e71f9..7af8b80 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -575,4 +575,7 @@
 
     <!-- Standard image button size for volume dialog buttons -->
     <dimen name="volume_button_size">48dp</dimen>
+
+    <!-- Padding between icon and text for managed profile toast -->
+    <dimen name="managed_profile_toast_padding">4dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a496548..f8a1385 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -393,13 +393,16 @@
                 if (recentTask != null && recentTask.size() > 0) {
                     UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId);
                     if (user != null && user.isManagedProfile()) {
-                        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                                Context.LAYOUT_INFLATER_SERVICE);
-                        View layout = inflater.inflate(R.layout.managed_profile_toast, null);
-                        Toast toast = new Toast(mContext);
-                        toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
-                        toast.setDuration(Toast.LENGTH_SHORT);
-                        toast.setView(layout);
+                        Toast toast = Toast.makeText(mContext,
+                                R.string.managed_profile_foreground_toast,
+                                Toast.LENGTH_SHORT);
+                        TextView text = (TextView) toast.getView().findViewById(
+                                android.R.id.message);
+                        text.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                                R.drawable.stat_sys_managed_profile_status, 0, 0, 0);
+                        int paddingPx = mContext.getResources().getDimensionPixelSize(
+                                R.dimen.managed_profile_toast_padding);
+                        text.setCompoundDrawablePadding(paddingPx);
                         toast.show();
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 3cc9297..daa84ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -154,6 +154,12 @@
     }
 
     private void updateConnected() {
+        // Make sure our connection state is up to date.
+        int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState();
+        if (state != mConnectionState) {
+            mConnectionState = state;
+            mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
+        }
         if (mLastDevice != null && mLastDevice.isConnected()) {
             // Our current device is still valid.
             return;
@@ -203,9 +209,9 @@
 
     @Override
     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
-        mConnectionState = state;
         mLastDevice = cachedDevice;
         updateConnected();
+        mConnectionState = state;
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 970deba..1134556 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3264,9 +3264,9 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
                 }
             }
-            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
-            if ("true".equals(genCFIDebugProperty)) {
-                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
+            if ("true".equals(genDebugInfoProperty)) {
+                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
             }
             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
@@ -8270,7 +8270,7 @@
                 try {
                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
                         allowed = true;
-                        Slog.w(TAG, caller + ": caller " + callingUid
+                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
                                 + " is using old GET_TASKS but privileged; allowing");
                     }
                 } catch (RemoteException e) {
@@ -8278,7 +8278,7 @@
             }
         }
         if (!allowed) {
-            Slog.w(TAG, caller + ": caller " + callingUid
+            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
                     + " does not hold REAL_GET_TASKS; limiting output");
         }
         return allowed;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9e33f2a..4e98576 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1915,7 +1915,12 @@
                 ActivityRecord intentActivity = !launchSingleInstance ?
                         findTaskLocked(r) : findActivityLocked(intent, r.info);
                 if (intentActivity != null) {
-                    if (isLockTaskModeViolation(intentActivity.task)) {
+                    // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
+                    // but still needs to be a lock task mode violation since the task gets
+                    // cleared out and the device would otherwise leave the locked task.
+                    if (isLockTaskModeViolation(intentActivity.task,
+                            (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                         showLockTaskToast();
                         Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                         return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
@@ -3780,7 +3785,11 @@
     }
 
     boolean isLockTaskModeViolation(TaskRecord task) {
-        if (getLockedTaskLocked() == task) {
+        return isLockTaskModeViolation(task, false);
+    }
+
+    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
+        if (getLockedTaskLocked() == task && !isNewClearTask) {
             return false;
         }
         final int lockTaskAuth = task.mLockTaskAuth;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 709ae54..e7fddb9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -12500,6 +12500,8 @@
                 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
                     scheduleWritePackageRestrictionsLocked(removeUser);
                 }
+                revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
+                        removeUser);
             }
             return true;
         }
@@ -12706,13 +12708,37 @@
                 | PackageManager.FLAG_PERMISSION_USER_FIXED
                 | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
 
+        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
+    }
+
+    /**
+     * Revokes granted runtime permissions and clears all flags.
+     *
+     * @param permissionsState The permission state to reset.
+     * @param userId The device user for which to do a reset.
+     */
+    private void revokeRuntimePermissionsAndClearAllFlagsLocked(
+            PermissionsState permissionsState, int userId) {
+        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
+                PackageManager.MASK_PERMISSION_FLAGS);
+    }
+
+    /**
+     * Revokes granted runtime permissions and clears certain flags.
+     *
+     * @param permissionsState The permission state to reset.
+     * @param userId The device user for which to do a reset.
+     * @param flags The flags that is going to be reset.
+     */
+    private void revokeRuntimePermissionsAndClearFlagsLocked(
+            PermissionsState permissionsState, int userId, int flags) {
         boolean needsWrite = false;
 
         for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
             BasePermission bp = mSettings.mPermissions.get(state.getName());
             if (bp != null) {
                 permissionsState.revokeRuntimePermission(bp, userId);
-                permissionsState.updatePermissionFlags(bp, userId, userSetFlags, 0);
+                permissionsState.updatePermissionFlags(bp, userId, flags, 0);
                 needsWrite = true;
             }
         }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cd50946..4b36581 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2098,7 +2098,7 @@
                 }
 
                 final ApplicationInfo ai = pkg.pkg.applicationInfo;
-                final String dataPath = ai.dataDir;
+                final String dataPath = new File(ai.dataDir).getCanonicalPath();
                 final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                 final int[] gids = pkg.getPermissionsState().computeGids(userIds);