Merge "Added support for static vs. dynamic stacks"
diff --git a/api/current.txt b/api/current.txt
index 6d9c18a..090e636 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22723,7 +22723,7 @@
     field public static final int KITKAT_WATCH = 20; // 0x14
     field public static final int LOLLIPOP = 21; // 0x15
     field public static final int LOLLIPOP_MR1 = 22; // 0x16
-    field public static final int MNC = 23; // 0x17
+    field public static final int M = 23; // 0x17
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 137e56c..0513b5a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24669,7 +24669,7 @@
     field public static final int KITKAT_WATCH = 20; // 0x14
     field public static final int LOLLIPOP = 21; // 0x15
     field public static final int LOLLIPOP_MR1 = 22; // 0x16
-    field public static final int MNC = 23; // 0x17
+    field public static final int M = 23; // 0x17
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 1de8f98..fb03b62 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -720,7 +720,7 @@
         }
 
         // Reject this timezone if it isn't an Olson zone we recognize.
-        if (mTargetSdkVersion >= Build.VERSION_CODES.MNC) {
+        if (mTargetSdkVersion >= Build.VERSION_CODES.M) {
             boolean hasTimeZone = false;
             try {
                 hasTimeZone = ZoneInfoDB.getInstance().hasTimeZone(timeZone);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 862d235..42ac67c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1234,6 +1234,14 @@
     }
 
     /** @hide */
+    public void setUidMode(int code, int uid, int mode) {
+        try {
+            mService.setUidMode(code, uid, mode);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /** @hide */
     public void setMode(int code, int uid, String packageName, int mode) {
         try {
             mService.setMode(code, uid, packageName, mode);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 7fbb99a..4b670cd 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -240,7 +240,7 @@
                 getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
             }
             final boolean targetsM = decorView == null || decorView.getContext()
-                    .getApplicationInfo().targetSdkVersion >= VERSION_CODES.MNC;
+                    .getApplicationInfo().targetSdkVersion >= VERSION_CODES.M;
             ArrayList<String> sharedElementNames = targetsM ? mSharedElementNames :
                     mAllSharedElementNames;
             ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b2b1727..f21422e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -112,7 +112,7 @@
      *
      * In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
      * extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
-     * As of {@link android.os.Build.VERSION_CODES#MNC}, it should contain the extra
+     * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported.
      *
@@ -417,7 +417,7 @@
      *
      * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
      * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
-     * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in
+     * Starting from {@link android.os.Build.VERSION_CODES#M}, this parameter accepts SHA-256 in
      * addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
@@ -590,7 +590,7 @@
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
      *
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#MNC}, the properties should contain
+     * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
@@ -603,7 +603,7 @@
      * @hide
      * This MIME type is used for starting the Device Owner provisioning that requires
      * new provisioning features introduced in API version
-     * {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
+     * {@link android.os.Build.VERSION_CODES#M} in addition to those supported in earlier
      * versions.
      *
      * <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -2415,7 +2415,7 @@
      * <p>The calling device admin must be a device or profile owner. If it is not, a
      * security exception will be thrown.
      *
-     * <p>From version {@link android.os.Build.VERSION_CODES#MNC} disabling screen capture also
+     * <p>From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also
      * blocks assist requests for all activities of the relevant user.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -2499,9 +2499,9 @@
      * this method; if it has not, a security exception will be thrown.
      *
      * <p>Calling this from a managed profile before version
-     * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception.
+     * {@link android.os.Build.VERSION_CODES#M} will throw a security exception.
      *
-     * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set:
+     * <p>From version {@link android.os.Build.VERSION_CODES#M} a profile owner can set:
      * <ul>
      * <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT}
      *      these will affect the profile's parent user.
@@ -3623,7 +3623,7 @@
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
      *
-     * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+     * @deprecated From {@link android.os.Build.VERSION_CODES#M}
      */
     @Deprecated
     public UserHandle createUser(@NonNull ComponentName admin, String name) {
@@ -3660,7 +3660,7 @@
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
      *
-     * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+     * @deprecated From {@link android.os.Build.VERSION_CODES#M}
      */
     @Deprecated
     public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
@@ -3914,7 +3914,7 @@
      * <p>Any packages that shares uid with an allowed package will also be allowed
      * to activate lock task.
      *
-     * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task
+     * From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
      * package list results in locked tasks belonging to those packages to be finished.
      *
      * This function can only be called by the device owner.
@@ -3982,14 +3982,14 @@
      * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
      * <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
      * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
-     *   This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+     *   This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards
      *   and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
      * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
-     *   This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards.
+     *   This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards.
      *   </li>
      * </ul>
      * <p>Changing the following settings has no effect as of
-     * {@link android.os.Build.VERSION_CODES#MNC}:
+     * {@link android.os.Build.VERSION_CODES#M}:
      * <ul>
      * <li>{@link Settings.Global#BLUETOOTH_ON}.
      *   Use {@link android.bluetooth.BluetoothAdapter#enable()} and
@@ -4344,7 +4344,7 @@
      * the permission grant state via {@link #setPermissionGrantState}.
      *
      * <p/>As this policy only acts on runtime permission requests, it only applies to applications
-     * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+     * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
      *
      * @param admin Which profile or device owner this request is associated with.
      * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
@@ -4388,7 +4388,7 @@
      * revoke the permission. It retains the previous grant, if any.
      *
      * <p/>Permissions can be granted or revoked only for applications built with a
-     * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+     * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
      *
      * @param admin Which profile or device owner this request is associated with.
      * @param packageName The application to grant or revoke a permission to.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index e08686c..6b720c0 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1106,7 +1106,7 @@
         @Override
         public void setAssistBlocked(boolean state) {
             mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
-                    | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
+                    | (state ? ViewNode.FLAGS_ASSIST_BLOCKED : 0);
         }
 
         @Override
@@ -1412,6 +1412,9 @@
         if (extras != null) {
             Log.i(TAG, prefix + "  Extras: " + extras);
         }
+        if (node.isAssistBlocked()) {
+            Log.i(TAG, prefix + "  BLOCKED");
+        }
         final int NCHILDREN = node.getChildCount();
         if (NCHILDREN > 0) {
             Log.i(TAG, prefix + "  Children:");
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 4d2158f..954ccef 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -415,7 +415,7 @@
      * if this method returns TRANSPORT_OK.  To avoid storing such payloads the transport
      * must recognize this case and return TRANSPORT_PACKAGE_REJECTED.
      *
-     * Added in MNC (API 23).
+     * Added in {@link android.os.Build.VERSION_CODES#M}.
      *
      * @param size The estimated size of the full-data payload for this app.  This includes
      *         manifest and archive format overhead, but is not guaranteed to be precise.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f786d2f..aaaa745 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1021,7 +1021,7 @@
      * numbers.  Applications can <strong>dial</strong> emergency numbers using
      * {@link #ACTION_DIAL}, however.
      *
-     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC}
+     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M}
      * and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
      * permission which is not granted, then attempting to use this action will
      * result in a {@link java.lang.SecurityException}.
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index d456b5e..5d405f9 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -19,7 +19,6 @@
 import android.annotation.SystemApi;
 import android.os.Build;
 import android.os.Handler;
-import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -1632,7 +1631,7 @@
         if (values == null) {
             throw new IllegalArgumentException("sensor data cannot be null");
         }
-        int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.MNC);
+        int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
         if (values.length != expectedNumValues) {
             throw new  IllegalArgumentException ("Wrong number of values for sensor " +
                     sensor.getName() + " actual=" + values.length + " expected=" +
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a82640f..10373cf 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -896,7 +896,7 @@
      *
      * @deprecated Deprecated in favor of the cleaner
      *             {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
-     *             In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
      *             throw {@code UnsupportedOperationException} if called.
      */
     public int startUsingNetworkFeature(int networkType, String feature) {
@@ -946,7 +946,7 @@
      * always indicates failure.
      *
      * @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API.
-     *             In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
      *             throw {@code UnsupportedOperationException} if called.
      */
     public int stopUsingNetworkFeature(int networkType, String feature) {
@@ -1364,7 +1364,7 @@
      * @deprecated Deprecated in favor of the
      *             {@link #requestNetwork(NetworkRequest, NetworkCallback)},
      *             {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
-     *             In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
      *             throw {@code UnsupportedOperationException} if called.
      */
     public boolean requestRouteToHost(int networkType, int hostAddress) {
@@ -2878,7 +2878,7 @@
             return;
         }
 
-        unsupportedStartingFrom(VERSION_CODES.MNC);
+        unsupportedStartingFrom(VERSION_CODES.M);
     }
 
     /**
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b2ced7f..a0162f7 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -622,7 +622,7 @@
         /**
          * M comes after L.
          */
-        public static final int MNC = 23;
+        public static final int M = 23;
     }
 
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7915a76..138be87 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -181,7 +181,7 @@
      * Specifies if a user is disallowed from configuring VPN.
      * The default value is <code>false</code>.
      * This restriction has an effect in a managed profile only from
-     * {@link android.os.Build.VERSION_CODES#MNC}
+     * {@link android.os.Build.VERSION_CODES#M}
      *
      * <p/>Key for user restrictions.
      * <p/>Type: Boolean
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index e63fb04..9babf43 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -284,7 +284,7 @@
      * If you don't set a ClipData, it will be copied there for you when calling
      * {@link Context#startActivity(Intent)}.
      *
-     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
      * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
      * is not granted, then atempting to use this action will result in a {@link
      * java.lang.SecurityException}.
@@ -338,7 +338,7 @@
      * If you don't set a ClipData, it will be copied there for you when calling
      * {@link Context#startActivity(Intent)}.
      *
-     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
      * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
      * is not granted, then atempting to use this action will result in a {@link
      * java.lang.SecurityException}.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 04f1e04..862207c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4434,7 +4434,7 @@
          *
          * @deprecated Use {@link android.app.KeyguardManager} to determine the state and security
          *             level of the keyguard. Accessing this setting from an app that is targeting
-         *             {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+         *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
         public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
@@ -4443,7 +4443,7 @@
          * Whether lock pattern is visible as user enters (0 = false, 1 = true)
          *
          * @deprecated Accessing this setting from an app that is targeting
-         *             {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+         *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
         public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
@@ -4456,7 +4456,7 @@
          *             lockscreen uses
          *             {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}.
          *             Accessing this setting from an app that is targeting
-         *             {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+         *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
         public static final String
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6de9cc7..17a9741 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,7 +56,6 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManagerGlobal;
-import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.Handler;
@@ -3809,14 +3808,14 @@
             // of whether a layout was requested on that View.
             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
 
-            Canvas.sCompatibilityRestore = targetSdkVersion < MNC;
+            Canvas.sCompatibilityRestore = targetSdkVersion < M;
 
-            // In MNC and newer, our widgets can pass a "hint" value in the size
+            // In M and newer, our widgets can pass a "hint" value in the size
             // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
             // know what the expected parent size is going to be, so e.g. list items can size
             // themselves at 1/3 the size of their container. It breaks older apps though,
             // specifically apps that use some popular open source libraries.
-            sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < MNC;
+            sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
 
             sCompatibilityDone = true;
         }
@@ -4284,27 +4283,27 @@
                             PROVIDER_BACKGROUND));
                     break;
                 case R.styleable.View_foreground:
-                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                    if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
                         setForeground(a.getDrawable(attr));
                     }
                     break;
                 case R.styleable.View_foregroundGravity:
-                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                    if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
                         setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
                     }
                     break;
                 case R.styleable.View_foregroundTintMode:
-                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                    if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
                         setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
                     }
                     break;
                 case R.styleable.View_foregroundTint:
-                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                    if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
                         setForegroundTintList(a.getColorStateList(attr));
                     }
                     break;
                 case R.styleable.View_foregroundInsidePadding:
-                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                    if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
                         if (mForegroundInfo == null) {
                             mForegroundInfo = new ForegroundInfo();
                         }
@@ -11424,10 +11423,10 @@
      * strongly recommended for performance reasons to either override
      * {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a
      * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration
-     * of the animation. On versions {@link android.os.Build.VERSION_CODES#MNC} and below,
+     * of the animation. On versions {@link android.os.Build.VERSION_CODES#M} and below,
      * the default path for rendering an unlayered View with alpha could add multiple milliseconds
      * of rendering cost, even for simple or small views. Starting with
-     * {@link android.os.Build.VERSION_CODES#MNC}, {@link #LAYER_TYPE_HARDWARE} is automatically
+     * {@link android.os.Build.VERSION_CODES#M}, {@link #LAYER_TYPE_HARDWARE} is automatically
      * applied to the view at the rendering level.</p>
      *
      * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
@@ -11438,7 +11437,7 @@
      * associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an
      * alpha value less than 1.0 will supersede the alpha of the layer paint.</p>
      *
-     * <p>Starting with {@link android.os.Build.VERSION_CODES#MNC}, setting a translucent alpha
+     * <p>Starting with {@link android.os.Build.VERSION_CODES#M}, setting a translucent alpha
      * value will clip a View to its bounds, unless the View returns <code>false</code> from
      * {@link #hasOverlappingRendering}.</p>
      *
@@ -18780,22 +18779,17 @@
         long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
         if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
 
-        final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
-        final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
-                MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
-        final boolean matchingSize = isExactly &&
-                getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
-                getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
-        if (forceLayout || !matchingSize &&
-                (widthMeasureSpec != mOldWidthMeasureSpec ||
-                        heightMeasureSpec != mOldHeightMeasureSpec)) {
+        if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
+                widthMeasureSpec != mOldWidthMeasureSpec ||
+                heightMeasureSpec != mOldHeightMeasureSpec) {
 
             // first clears the measured dimension flag
             mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
 
             resolveRtlPropertiesIfNeeded();
 
-            int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
+            int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
+                    mMeasureCache.indexOfKey(key);
             if (cacheIndex < 0 || sIgnoreMeasureCache) {
                 // measure ourselves, this should set the measured dimension flag back
                 onMeasure(widthMeasureSpec, heightMeasureSpec);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a6639d5..bc19b40 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5488,7 +5488,7 @@
      * @see #setAnimationCacheEnabled(boolean)
      * @see View#setDrawingCacheEnabled(boolean)
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
      */
     public boolean isAnimationCacheEnabled() {
@@ -5506,7 +5506,7 @@
      * @see #isAnimationCacheEnabled()
      * @see View#setDrawingCacheEnabled(boolean)
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
      */
     public void setAnimationCacheEnabled(boolean enabled) {
@@ -5523,7 +5523,7 @@
      * @see #setChildrenDrawnWithCacheEnabled(boolean)
      * @see View#setDrawingCacheEnabled(boolean)
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Child views may no longer have their caching behavior disabled by parents.
      */
     public boolean isAlwaysDrawnWithCacheEnabled() {
@@ -5547,7 +5547,7 @@
      * @see View#setDrawingCacheEnabled(boolean)
      * @see View#setDrawingCacheQuality(int)
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Child views may no longer have their caching behavior disabled by parents.
      */
     public void setAlwaysDrawnWithCacheEnabled(boolean always) {
@@ -5563,7 +5563,7 @@
      * @see #setAlwaysDrawnWithCacheEnabled(boolean)
      * @see #setChildrenDrawnWithCacheEnabled(boolean)
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Child views may no longer be forced to cache their rendering state by their parents.
      * Use {@link View#setLayerType(int, Paint)} on individual Views instead.
      */
@@ -5584,7 +5584,7 @@
      * @see #setAlwaysDrawnWithCacheEnabled(boolean)
      * @see #isChildrenDrawnWithCacheEnabled()
      *
-     * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
      * Child views may no longer be forced to cache their rendering state by their parents.
      * Use {@link View#setLayerType(int, Paint)} on individual Views instead.
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fdfc48a5..fb02e7e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -79,7 +79,6 @@
 import com.android.internal.R;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.policy.PhoneFallbackEventHandler;
-import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.view.BaseSurfaceHolder;
 import com.android.internal.view.RootViewSurfaceTaker;
 
@@ -5821,7 +5820,7 @@
     }
 
     private void adjustInputEventForCompatibility(InputEvent e) {
-        if (mTargetSdkVersion < Build.VERSION_CODES.MNC && e instanceof MotionEvent) {
+        if (mTargetSdkVersion < Build.VERSION_CODES.M && e instanceof MotionEvent) {
             MotionEvent motion = (MotionEvent) e;
             final int mask =
                 MotionEvent.BUTTON_STYLUS_PRIMARY | MotionEvent.BUTTON_STYLUS_SECONDARY;
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 76c8fbd..6130fd5 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -303,10 +303,12 @@
      * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and prior, do not trust this package
      * name. The system had not verified the consistency between the package name here and
      * application's uid. Consider to use {@link InputBinding#getUid()}, which is trustworthy.
-     * Starting from Android MNC, the system verifies the consistency between this package name
-     * and application uid before {@link EditorInfo} is passed to the input method.</p>
+     * Starting from {@link android.os.Build.VERSION_CODES#M}, the system verifies the consistency
+     * between this package name and application uid before {@link EditorInfo} is passed to the
+     * input method.</p>
      *
-     * <p><strong>Editor authors:</strong> Starting from Android MNC, the application is no longer
+     * <p><strong>Editor authors:</strong> Starting from {@link android.os.Build.VERSION_CODES#M},
+     * the application is no longer
      * able to establish input connections if the package name provided here is inconsistent with
      * application's uid.</p>
      */
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 47e894a..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -686,7 +686,6 @@
         int weightedMaxWidth = 0;
         boolean allFillParent = true;
         float totalWeight = 0;
-        int usedExcessSpace = 0;
 
         final int count = getVirtualChildCount();
         
@@ -722,10 +721,8 @@
             LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
 
             totalWeight += lp.weight;
-
-            final boolean fillExcessSpace = lp.weight > 0;
-            final boolean hasZeroHeight = lp.height == 0;
-            if (heightMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroHeight) {
+            
+            if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
                 // Optimization: don't bother measuring children who are going to use
                 // leftover space. These views will get measured again down below if
                 // there is any leftover space.
@@ -733,12 +730,14 @@
                 mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
                 skippedMeasure = true;
             } else {
-                if (fillExcessSpace && hasZeroHeight) {
-                    // The LinearLayout's heightMode is either UNSPECIFIED or
-                    // AT_MOST, and this child wanted to stretch to fill
-                    // available space. Translate the explicit height of 0 to
-                    // WRAP_CONTENT so that we can measure the view's ideal
-                    // height.
+                int oldHeight = Integer.MIN_VALUE;
+
+                if (lp.height == 0 && lp.weight > 0) {
+                    // heightMode is either UNSPECIFIED or AT_MOST, and this
+                    // child wanted to stretch to fill available space.
+                    // Translate that to WRAP_CONTENT so that it does not end up
+                    // with a height of 0
+                    oldHeight = 0;
                     lp.height = LayoutParams.WRAP_CONTENT;
                 }
 
@@ -750,16 +749,11 @@
                        child, i, widthMeasureSpec, 0, heightMeasureSpec,
                        totalWeight == 0 ? mTotalLength : 0);
 
-                final int childHeight = child.getMeasuredHeight();
-                if (fillExcessSpace) {
-                    usedExcessSpace += childHeight;
-
-                    // Restore original layout height.
-                    if (hasZeroHeight) {
-                        lp.height = 0;
-                    }
+                if (oldHeight != Integer.MIN_VALUE) {
+                   lp.height = oldHeight;
                 }
 
+                final int childHeight = child.getMeasuredHeight();
                 final int totalLength = mTotalLength;
                 mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
                        lp.bottomMargin + getNextLocationOffset(child));
@@ -863,7 +857,7 @@
         // Either expand children with weight to take up available space or
         // shrink them if they extend beyond our current bounds. If we skipped
         // measurement on any children, we need to measure them now.
-        final int delta = heightSize - mTotalLength + usedExcessSpace;
+        int delta = heightSize - mTotalLength;
         if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
@@ -880,14 +874,34 @@
                 
                 float childExtra = lp.weight;
                 if (childExtra > 0) {
-                    // Distribute excess space to child.
-                    final int childHeight = Math.max(0, (int) (childExtra * delta / weightSum));
-                    final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,
-                            MeasureSpec.EXACTLY);
+                    // Child said it could absorb extra space -- give him his share
+                    int share = (int) (childExtra * delta / weightSum);
+                    weightSum -= childExtra;
+                    delta -= share;
+
                     final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
-                            mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
-                            lp.width);
-                    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+                            mPaddingLeft + mPaddingRight +
+                                    lp.leftMargin + lp.rightMargin, lp.width);
+
+                    // TODO: Use a field like lp.isMeasured to figure out if this
+                    // child has been previously measured
+                    if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) {
+                        // child was measured once already above...
+                        // base new measurement on stored values
+                        int childHeight = child.getMeasuredHeight() + share;
+                        if (childHeight < 0) {
+                            childHeight = 0;
+                        }
+                        
+                        child.measure(childWidthMeasureSpec,
+                                MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+                    } else {
+                        // child was skipped in the loop above.
+                        // Measure for this first time here      
+                        child.measure(childWidthMeasureSpec,
+                                MeasureSpec.makeMeasureSpec(share > 0 ? share : 0,
+                                        MeasureSpec.EXACTLY));
+                    }
 
                     // Child may now not fit in vertical dimension.
                     childState = combineMeasuredStates(childState, child.getMeasuredState()
@@ -1003,7 +1017,6 @@
         int weightedMaxHeight = 0;
         boolean allFillParent = true;
         float totalWeight = 0;
-        int usedExcessSpace = 0;
 
         final int count = getVirtualChildCount();
         
@@ -1053,10 +1066,8 @@
                     child.getLayoutParams();
 
             totalWeight += lp.weight;
-
-            final boolean fillExcessSpace = lp.weight > 0;
-            final boolean hasZeroWidth = lp.width == 0;
-            if (widthMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroWidth) {
+            
+            if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
                 // Optimization: don't bother measuring children who are going to use
                 // leftover space. These views will get measured again down below if
                 // there is any leftover space.
@@ -1083,12 +1094,14 @@
                     skippedMeasure = true;
                 }
             } else {
-                if (fillExcessSpace && hasZeroWidth) {
-                    // The LinearLayout's widthMode is either UNSPECIFIED or
-                    // AT_MOST, and this child wanted to stretch to fill
-                    // available space. Translate the explicit height of 0 to
-                    // WRAP_CONTENT so that we can measure the view's ideal
-                    // width.
+                int oldWidth = Integer.MIN_VALUE;
+
+                if (lp.width == 0 && lp.weight > 0) {
+                    // widthMode is either UNSPECIFIED or AT_MOST, and this
+                    // child
+                    // wanted to stretch to fill available space. Translate that to
+                    // WRAP_CONTENT so that it does not end up with a width of 0
+                    oldWidth = 0;
                     lp.width = LayoutParams.WRAP_CONTENT;
                 }
 
@@ -1100,16 +1113,11 @@
                         totalWeight == 0 ? mTotalLength : 0,
                         heightMeasureSpec, 0);
 
-                final int childWidth = child.getMeasuredWidth();
-                if (fillExcessSpace) {
-                    usedExcessSpace += childWidth;
-
-                    // Restore the original layout width.
-                    if (hasZeroWidth) {
-                        lp.width = 0;
-                    }
+                if (oldWidth != Integer.MIN_VALUE) {
+                    lp.width = oldWidth;
                 }
 
+                final int childWidth = child.getMeasuredWidth();
                 if (isExactly) {
                     mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
                             getNextLocationOffset(child);
@@ -1234,7 +1242,7 @@
         // Either expand children with weight to take up available space or
         // shrink them if they extend beyond our current bounds. If we skipped
         // measurement on any children, we need to measure them now.
-        final int delta = widthSize - mTotalLength + usedExcessSpace;
+        int delta = widthSize - mTotalLength;
         if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
@@ -1257,13 +1265,34 @@
                 float childExtra = lp.weight;
                 if (childExtra > 0) {
                     // Child said it could absorb extra space -- give him his share
-                    final int childWidth = Math.max(0, (int) (childExtra * delta / weightSum));
-                    final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,
-                            MeasureSpec.EXACTLY);
-                    final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                    int share = (int) (childExtra * delta / weightSum);
+                    weightSum -= childExtra;
+                    delta -= share;
+
+                    final int childHeightMeasureSpec = getChildMeasureSpec(
+                            heightMeasureSpec,
                             mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin,
                             lp.height);
-                    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+                    // TODO: Use a field like lp.isMeasured to figure out if this
+                    // child has been previously measured
+                    if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
+                        // child was measured once already above ... base new measurement
+                        // on stored values
+                        int childWidth = child.getMeasuredWidth() + share;
+                        if (childWidth < 0) {
+                            childWidth = 0;
+                        }
+
+                        child.measure(
+                            MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+                            childHeightMeasureSpec);
+                    } else {
+                        // child was skipped in the loop above. Measure for this first time here
+                        child.measure(MeasureSpec.makeMeasureSpec(
+                                share > 0 ? share : 0, MeasureSpec.EXACTLY),
+                                childHeightMeasureSpec);
+                    }
 
                     // Child may now not fit in horizontal dimension.
                     childState = combineMeasuredStates(childState,
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 58a94b9..529d295 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -356,7 +356,7 @@
                 final int heightPadding;
                 final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
                 final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
-                if (targetSdkVersion >= VERSION_CODES.MNC) {
+                if (targetSdkVersion >= VERSION_CODES.M) {
                     widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
                     heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
                 } else {
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 73c4833..9fa2c23 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -38,6 +38,7 @@
     int checkPackage(int uid, String packageName);
     List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
     List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
+    void setUidMode(int code, int uid, int mode);
     void setMode(int code, int uid, String packageName, int mode);
     void resetAllModes(int reqUserId, String reqPackageName);
     int checkAudioOperation(int code, int usage, int uid, String packageName);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 43f7ebc..2b39528 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -32,7 +32,6 @@
 
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
-import android.view.Display;
 import android.view.Gravity;
 import android.view.IRotationWatcher.Stub;
 import android.view.IWindowManager;
@@ -3517,7 +3516,7 @@
             public void onDestroyActionMode(ActionMode mode) {
                 mWrapped.onDestroyActionMode(mode);
                 final boolean isMncApp = mContext.getApplicationInfo().targetSdkVersion
-                        >= Build.VERSION_CODES.MNC;
+                        >= Build.VERSION_CODES.M;
                 final boolean isPrimary;
                 final boolean isFloating;
                 if (isMncApp) {
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1515703..de16f20 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -219,7 +219,7 @@
         <flag name="appop" value="0x40" />
         <!-- Additional flag from base permission type: this permission can be automatically
              granted to apps that target API levels below
-             {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
+             {@link android.os.Build.VERSION_CODES#M} (before runtime permissions
              were introduced). -->
         <flag name="pre23" value="0x80" />
         <!-- Additional flag from base permission type: this permission can be automatically
@@ -1059,7 +1059,7 @@
          at the same time.
 
          <p>The default value is <code>false</code> for applications with
-         <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#MNC} and
+         <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#M} and
          <code>true</code> otherwise.
 
          <p>NOTE: A task's root activity value is applied to all additional activities launched in
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3c838b2a..cabb56c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2604,7 +2604,7 @@
     <public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
 
   <!-- ===============================================================
-       Resources added in version MNC of the platform
+       Resources added in version M of the platform
        =============================================================== -->
     <eat-comment />
 
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index c29ec0d..bde3d19 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -54,7 +54,7 @@
  * can be played on a device operating at a sample rate of 48000Hz; the sample rate conversion is
  * automatically handled by the platform, it will not play at 6x speed.
  *
- * <p>As of API {@link android.os.Build.VERSION_CODES#MNC},
+ * <p>As of API {@link android.os.Build.VERSION_CODES#M},
  * sample rates up to 192kHz are supported
  * for <code>AudioRecord</code> and <code>AudioTrack</code>, with sample rate conversion
  * performed as needed.
@@ -99,7 +99,7 @@
  * Floats are efficiently manipulated by modern CPUs,
  * have greater precision than 24 bit signed integers,
  * and have greater dynamic range than 32 bit signed integers.
- * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#MNC} and
+ * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#M} and
  * <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
  * support <code>ENCODING_PCM_FLOAT</code>.
  * </li>
@@ -123,7 +123,7 @@
  * the samples and their arrangement in the audio frame. They are also used in the endpoint (e.g.
  * a USB audio interface, a DAC connected to headphones) to specify allowable configurations of a
  * particular device.
- * <br>As of API {@link android.os.Build.VERSION_CODES#MNC}, there are two types of channel masks:
+ * <br>As of API {@link android.os.Build.VERSION_CODES#M}, there are two types of channel masks:
  * channel position masks and channel index masks.
  *
  * <h5 id="channelPositionMask">Channel position masks</h5>
@@ -152,7 +152,7 @@
  * {@link #CHANNEL_OUT_FRONT_RIGHT}.
  *
  * <h5 id="channelIndexMask">Channel index masks</h5>
- * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#MNC}. They allow
+ * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#M}. They allow
  * the selection of a particular channel from the source or sink endpoint by number, i.e. the first
  * channel, the second channel, and so forth. This avoids problems with artificially assigning
  * positions to channels of an endpoint, or figuring what the i<sup>th</sup> position bit is within
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 62810c6..8880dad 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -27,7 +27,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.app.ActivityThread;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -1174,9 +1173,12 @@
     * Poll for a timestamp on demand.
     * <p>
     * If you need to track timestamps during initial warmup or after a routing or mode change,
-    * you should request a new timestamp once per second until the reported timestamps
-    * show that the audio clock is stable.
-    * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute.
+    * you should request a new timestamp periodically until the reported timestamps
+    * show that the frame position is advancing, or until it becomes clear that
+    * timestamps are unavailable for this route.
+    * <p>
+    * After the clock is advancing at a stable rate,
+    * query for a new timestamp approximately once every 10 seconds to once per minute.
     * Calling this method more often is inefficient.
     * It is also counter-productive to call this method more often than recommended,
     * because the short-term differences between successive timestamp reports are not meaningful.
@@ -1199,6 +1201,11 @@
     *         In the case that no timestamp is available, any supplied instance is left unaltered.
     *         A timestamp may be temporarily unavailable while the audio clock is stabilizing,
     *         or during and immediately after a route change.
+    *         A timestamp is permanently unavailable for a given route if the route does not support
+    *         timestamps.  In this case, the approximate frame position can be obtained
+    *         using {@link #getPlaybackHeadPosition}.
+    *         However, it may be useful to continue to query for
+    *         timestamps occasionally, to recover after a route change.
     */
     // Add this text when the "on new timestamp" API is added:
     //   Use if you need to get the most recent timestamp outside of the event callback handler.
@@ -1409,7 +1416,7 @@
      * <br>
      * If looping is currently enabled and the new position is greater than or equal to the
      * loop end marker, the behavior varies by API level:
-     * as of {@link android.os.Build.VERSION_CODES#MNC},
+     * as of {@link android.os.Build.VERSION_CODES#M},
      * the looping is first disabled and then the position is set.
      * For earlier API levels, the behavior is unspecified.
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
@@ -1446,7 +1453,7 @@
      * {@link #ERROR_BAD_VALUE} is returned.
      * The loop range is the interval [startInFrames, endInFrames).
      * <br>
-     * As of {@link android.os.Build.VERSION_CODES#MNC}, the position is left unchanged,
+     * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
      * unless it is greater than or equal to the loop end marker, in which case
      * it is forced to the loop start marker.
      * For earlier API levels, the effect on position is unspecified.
@@ -2077,7 +2084,7 @@
      * The track must be stopped or paused, and
      * the track's creation mode must be {@link #MODE_STATIC}.
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#MNC}, also resets the value returned by
+     * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
      * {@link #getPlaybackHeadPosition()} to zero.
      * For earlier API levels, the reset behavior is unspecified.
      * <p>
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 5f60891..3c459d8 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -21,12 +21,7 @@
 import android.annotation.Nullable;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
-import android.media.Image;
-import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaCrypto;
-import android.media.MediaFormat;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -510,11 +505,11 @@
  #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li>
  </ul>
  <p>
- Since {@link android.os.Build.VERSION_CODES#MNC}, the default timestamp is the {@linkplain
+ Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain
  BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds).
  It was not defined prior to that.
  <p>
- Also since {@link android.os.Build.VERSION_CODES#MNC}, you can change the output Surface
+ Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
  dynamically using {@link #setOutputSurface setOutputSurface}.
 
  <h4>Using an Input Surface</h4>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 3670683..5183c35 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -142,6 +142,8 @@
     private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
     private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
     private static final int MSG_SERVICE_STATE_CHANGE = 330;
+    private static final int MSG_SCREEN_TURNED_ON = 331;
+    private static final int MSG_SCREEN_TURNED_OFF = 332;
 
     private static KeyguardUpdateMonitor sInstance;
 
@@ -248,6 +250,12 @@
                 case MSG_SERVICE_STATE_CHANGE:
                     handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
                     break;
+                case MSG_SCREEN_TURNED_ON:
+                    handleScreenTurnedOn();
+                    break;
+                case MSG_SCREEN_TURNED_OFF:
+                    handleScreenTurnedOff();
+                    break;
             }
         }
     };
@@ -806,6 +814,26 @@
         updateFingerprintListeningState();
     }
 
+    private void handleScreenTurnedOn() {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onScreenTurnedOn();
+            }
+        }
+    }
+
+    private void handleScreenTurnedOff() {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onScreenTurnedOff();
+            }
+        }
+    }
+
     /**
      * IMPORTANT: Must be called from UI thread.
      */
@@ -1486,12 +1514,14 @@
         synchronized (this) {
             mScreenOn = true;
         }
+        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
     }
 
     public void dispatchScreenTurnedOff() {
         synchronized(this) {
             mScreenOn = false;
         }
+        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
     }
 
     public boolean isDeviceInteractive() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0cdf999..6cda2b7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -161,6 +161,16 @@
     public void onFinishedGoingToSleep(int why) { }
 
     /**
+     * Called when the screen has been turned on.
+     */
+    public void onScreenTurnedOn() { }
+
+    /**
+     * Called when the screen has been turned off.
+     */
+    public void onScreenTurnedOff() { }
+
+    /**
      * Called when trust changes for a user.
      */
     public void onTrustChanged(int userId) { }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 49e6740..bafccae 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -46,6 +46,7 @@
 import android.util.Slog;
 import android.util.Xml;
 
+import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.printspooler.R;
@@ -493,6 +494,7 @@
                     Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob);
                 }
 
+                MetricsLogger.histogram(this, "print_job_state", state);
                 switch (state) {
                     case PrintJobInfo.STATE_COMPLETED:
                     case PrintJobInfo.STATE_CANCELED:
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 6baa4b3..e8a5e43 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -72,6 +72,7 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import com.android.internal.logging.MetricsLogger;
 import com.android.printspooler.R;
 import com.android.printspooler.model.MutexFileProvider;
 import com.android.printspooler.model.PrintSpoolerProvider;
@@ -325,6 +326,7 @@
         if (mState != STATE_INITIALIZING && mCurrentPrinter != null) {
             mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId());
         }
+        MetricsLogger.count(this, "print_preview", 1);
     }
 
     @Override
@@ -1074,6 +1076,8 @@
     private void confirmPrint() {
         setState(STATE_PRINT_CONFIRMED);
 
+        MetricsLogger.count(this, "print_confirmed", 1);
+
         updateOptionsUi();
         addCurrentPrinterToHistory();
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 6e3a29d..14fba2b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -48,6 +48,8 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -86,6 +88,15 @@
     final static String TAG = "SystemServicesProxy";
 
     final static BitmapFactory.Options sBitmapOptions;
+    final static HandlerThread sBgThread;
+
+    static {
+        sBgThread = new HandlerThread("Recents-SystemServicesProxy",
+                android.os.Process.THREAD_PRIORITY_BACKGROUND);
+        sBgThread.start();
+        sBitmapOptions = new BitmapFactory.Options();
+        sBitmapOptions.inMutable = true;
+    }
 
     AccessibilityManager mAccm;
     ActivityManager mAm;
@@ -99,17 +110,14 @@
     String mRecentsPackage;
     ComponentName mAssistComponent;
 
+    Handler mBgThreadHandler;
+
     Bitmap mDummyIcon;
     int mDummyThumbnailWidth;
     int mDummyThumbnailHeight;
     Paint mBgProtectionPaint;
     Canvas mBgProtectionCanvas;
 
-    static {
-        sBitmapOptions = new BitmapFactory.Options();
-        sBitmapOptions.inMutable = true;
-    }
-
     /** Private constructor */
     public SystemServicesProxy(Context context) {
         mAccm = AccessibilityManager.getInstance(context);
@@ -122,6 +130,7 @@
         mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         mDisplay = mWm.getDefaultDisplay();
         mRecentsPackage = context.getPackageName();
+        mBgThreadHandler = new Handler(sBgThread.getLooper());
 
         // Get the dummy thumbnail width/heights
         Resources res = context.getResources();
@@ -373,12 +382,17 @@
     }
 
     /** Removes the task */
-    public void removeTask(int taskId) {
+    public void removeTask(final int taskId) {
         if (mAm == null) return;
         if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
 
         // Remove the task.
-        mAm.removeTask(taskId);
+        mBgThreadHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mAm.removeTask(taskId);
+            }
+        });
     }
 
     /**
@@ -646,22 +660,6 @@
         return windowRect;
     }
 
-    /**
-     * Takes a screenshot of the current surface.
-     */
-    public Bitmap takeScreenshot() {
-        DisplayInfo di = new DisplayInfo();
-        mDisplay.getDisplayInfo(di);
-        return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight());
-    }
-
-    /**
-     * Takes a screenshot of the current app.
-     */
-    public Bitmap takeAppScreenshot() {
-        return takeScreenshot();
-    }
-
     /** Starts an activity from recents. */
     public boolean startActivityFromRecents(Context context, int taskId, String taskName,
             ActivityOptions options) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index b2aa2b6..ad25c85 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -343,11 +343,14 @@
         if (infoHandle.info != null) {
             label = ssp.getActivityLabel(infoHandle.info);
             mActivityLabelCache.put(taskKey, label);
+            return label;
         } else {
             Log.w(TAG, "Missing ActivityInfo for " + taskKey.baseIntent.getComponent()
                     + " u=" + taskKey.userId);
         }
-        return label;
+        // If the activity info does not exist or fails to load, return an empty label for now,
+        // but do not cache it
+        return "";
     }
 
     /** Returns the content description using as many cached values as we can. */
@@ -358,14 +361,22 @@
         if (label != null) {
             return label;
         }
+        // If the given activity label is empty, don't compute or cache the content description
+        if (activityLabel.isEmpty()) {
+            return "";
+        }
+
         label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res);
         if (label != null) {
             mContentDescriptionCache.put(taskKey, label);
+            return label;
         } else {
             Log.w(TAG, "Missing content description for " + taskKey.baseIntent.getComponent()
                     + " u=" + taskKey.userId);
         }
-        return label;
+        // If the content description does not exist, return an empty label for now, but do not
+        // cache it
+        return "";
     }
 
     /** Returns the activity icon using as many cached values as we can. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 78b3512..2e0b80a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -316,7 +316,7 @@
                                     overscrollRange);
                     // Invalidate to kick off computeScroll
                     mSv.invalidate();
-                } else if (mScroller.isScrollOutOfBounds()) {
+                } else if (mIsScrolling && mScroller.isScrollOutOfBounds()) {
                     // Animate the scroll back into bounds
                     mScroller.animateBoundScroll();
                 } else if (mActiveTaskView == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index ccec759..71baf57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -374,7 +374,11 @@
     }
 
     private void updateClipping() {
-        mClipRect.set(0, mClipTopOptimization, getWidth(), getActualHeight());
+        int top = mClipTopOptimization;
+        if (top >= getActualHeight()) {
+            top = getActualHeight() - 1;
+        }
+        mClipRect.set(0, top, getWidth(), getActualHeight());
         setClipBounds(mClipRect);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 6627360..8e5d4d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -644,6 +644,16 @@
         }
 
         @Override
+        public void onScreenTurnedOn() {
+            mLockIcon.setScreenOn(true);
+        }
+
+        @Override
+        public void onScreenTurnedOff() {
+            mLockIcon.setScreenOn(false);
+        }
+
+        @Override
         public void onKeyguardVisibilityChanged(boolean showing) {
             mLockIcon.update();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 06d2fca..463abfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -34,12 +34,6 @@
  */
 public class LockIcon extends KeyguardAffordanceView {
 
-    /**
-     * Delay animations a bit when the screen just turned on as a heuristic to start them after
-     * the screen has actually turned on.
-     */
-    private static final long ANIM_DELAY_AFTER_SCREEN_ON = 250;
-
     private static final int STATE_LOCKED = 0;
     private static final int STATE_LOCK_OPEN = 1;
     private static final int STATE_FACE_UNLOCK = 2;
@@ -50,6 +44,8 @@
     private boolean mLastDeviceInteractive;
     private boolean mTransientFpError;
     private boolean mDeviceInteractive;
+    private boolean mScreenOn;
+    private boolean mLastScreenOn;
     private final TrustDrawable mTrustDrawable;
     private final UnlockMethodCache mUnlockMethodCache;
     private AccessibilityController mAccessibilityController;
@@ -88,6 +84,11 @@
         update();
     }
 
+    public void setScreenOn(boolean screenOn) {
+        mScreenOn = screenOn;
+        update();
+    }
+
     public void update() {
         boolean visible = isShown()
                 && KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
@@ -96,20 +97,20 @@
         } else {
             mTrustDrawable.stop();
         }
-        if (!visible) {
-            return;
-        }
         // TODO: Real icon for facelock.
         int state = getState();
         boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
-        if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive) {
+        if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
+                || mScreenOn != mLastScreenOn) {
+            boolean isAnim = true;
             int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
-                    mDeviceInteractive);
+                    mDeviceInteractive, mLastScreenOn, mScreenOn);
             if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
                 anyFingerprintIcon = true;
             }
             if (iconRes == -1) {
-                iconRes = getIconForState(state);
+                iconRes = getIconForState(state, mScreenOn, mDeviceInteractive);
+                isAnim = false;
             }
             Drawable icon = mContext.getDrawable(iconRes);
             final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
@@ -135,23 +136,12 @@
                     : R.string.accessibility_unlock_button);
             setContentDescription(contentDescription);
             mHasFingerPrintIcon = anyFingerprintIcon;
-            if (animation != null) {
-
-                // If we play the draw on animation, delay it by one frame when the screen is
-                // actually turned on.
-                if (iconRes == R.drawable.lockscreen_fingerprint_draw_on_animation) {
-                    postOnAnimationDelayed(new Runnable() {
-                        @Override
-                        public void run() {
-                            animation.start();
-                        }
-                    }, ANIM_DELAY_AFTER_SCREEN_ON);
-                } else {
-                    animation.start();
-                }
+            if (animation != null && isAnim) {
+                animation.start();
             }
             mLastState = state;
             mLastDeviceInteractive = mDeviceInteractive;
+            mLastScreenOn = mScreenOn;
         }
 
         // Hide trust circle when fingerprint is running.
@@ -192,7 +182,7 @@
         mAccessibilityController = accessibilityController;
     }
 
-    private int getIconForState(int state) {
+    private int getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
         switch (state) {
             case STATE_LOCKED:
                 return R.drawable.ic_lock_24dp;
@@ -201,7 +191,11 @@
             case STATE_FACE_UNLOCK:
                 return com.android.internal.R.drawable.ic_account_circle;
             case STATE_FINGERPRINT:
-                return R.drawable.ic_fingerprint;
+                // If screen is off and device asleep, use the draw on animation so the first frame
+                // gets drawn.
+                return screenOn && deviceInteractive
+                        ? R.drawable.ic_fingerprint
+                        : R.drawable.lockscreen_fingerprint_draw_on_animation;
             case STATE_FINGERPRINT_ERROR:
                 return R.drawable.ic_fingerprint_error;
             default:
@@ -209,8 +203,9 @@
         }
     }
 
-    private int getAnimationResForTransition(int oldState, int newState, boolean oldScreenOn,
-            boolean screenOn) {
+    private int getAnimationResForTransition(int oldState, int newState,
+            boolean oldDeviceInteractive, boolean deviceInteractive,
+            boolean oldScreenOn, boolean screenOn) {
         if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
             return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
         } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
@@ -218,7 +213,8 @@
         } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
                 && !mUnlockMethodCache.isTrusted()) {
             return R.drawable.lockscreen_fingerprint_draw_off_animation;
-        } else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
+        } else if (newState == STATE_FINGERPRINT && (!oldScreenOn && screenOn && deviceInteractive
+                || screenOn && !oldDeviceInteractive && deviceInteractive)) {
             return R.drawable.lockscreen_fingerprint_draw_on_animation;
         } else {
             return -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5d2e5b7..82064a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -413,7 +413,9 @@
         ExpandableNotificationRow topHeadsUpEntry = ambientState.getTopHeadsUpEntry();
 
         int childCount = algorithmState.visibleChildren.size();
-        int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack;
+        int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f
+                ? algorithmState.lastTopStackIndex
+                : (int) algorithmState.itemsInTopStack;
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             StackViewState childViewState = resultState.getViewStateForView(child);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 417f18d..ec02789 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -32,6 +32,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityThread;
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -56,15 +57,18 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.os.Zygote;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
+import libcore.util.EmptyArray;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -98,19 +102,38 @@
         }
     };
 
-    final SparseArray<HashMap<String, Ops>> mUidOps
-            = new SparseArray<HashMap<String, Ops>>();
+    final SparseArray<UidState> mUidStates = new SparseArray<>();
 
     private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
 
+    private static final class UidState {
+        public final int uid;
+        public ArrayMap<String, Ops> pkgOps;
+        public SparseIntArray opModes;
+
+        public UidState(int uid) {
+            this.uid = uid;
+        }
+
+        public void clear() {
+            pkgOps = null;
+            opModes = null;
+        }
+
+        public boolean isDefault() {
+            return (pkgOps == null || pkgOps.isEmpty())
+                    && (opModes == null || opModes.size() <= 0);
+        }
+    }
+
     public final static class Ops extends SparseArray<Op> {
         public final String packageName;
-        public final int uid;
+        public final UidState uidState;
         public final boolean isPrivileged;
 
-        public Ops(String _packageName, int _uid, boolean _isPrivileged) {
+        public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
             packageName = _packageName;
-            uid = _uid;
+            uidState = _uidState;
             isPrivileged = _isPrivileged;
         }
     }
@@ -220,27 +243,42 @@
     public void systemReady() {
         synchronized (this) {
             boolean changed = false;
-            for (int i=0; i<mUidOps.size(); i++) {
-                HashMap<String, Ops> pkgs = mUidOps.valueAt(i);
+            for (int i = mUidStates.size() - 1; i >= 0; i--) {
+                UidState uidState = mUidStates.valueAt(i);
+
+                String[] packageNames = getPackagesForUid(uidState.uid);
+                if (ArrayUtils.isEmpty(packageNames)) {
+                    uidState.clear();
+                    mUidStates.removeAt(i);
+                    changed = true;
+                    continue;
+                }
+
+                ArrayMap<String, Ops> pkgs = uidState.pkgOps;
+                if (pkgs == null) {
+                    continue;
+                }
+
                 Iterator<Ops> it = pkgs.values().iterator();
                 while (it.hasNext()) {
                     Ops ops = it.next();
                     int curUid;
                     try {
                         curUid = mContext.getPackageManager().getPackageUid(ops.packageName,
-                                UserHandle.getUserId(ops.uid));
+                                UserHandle.getUserId(ops.uidState.uid));
                     } catch (NameNotFoundException e) {
                         curUid = -1;
                     }
-                    if (curUid != ops.uid) {
+                    if (curUid != ops.uidState.uid) {
                         Slog.i(TAG, "Pruning old package " + ops.packageName
-                                + "/" + ops.uid + ": new uid=" + curUid);
+                                + "/" + ops.uidState + ": new uid=" + curUid);
                         it.remove();
                         changed = true;
                     }
                 }
-                if (pkgs.size() <= 0) {
-                    mUidOps.removeAt(i);
+
+                if (uidState.isDefault()) {
+                    mUidStates.removeAt(i);
                 }
             }
             if (changed) {
@@ -279,22 +317,34 @@
 
     public void packageRemoved(int uid, String packageName) {
         synchronized (this) {
-            HashMap<String, Ops> pkgs = mUidOps.get(uid);
-            if (pkgs != null) {
-                if (pkgs.remove(packageName) != null) {
-                    if (pkgs.size() <= 0) {
-                        mUidOps.remove(uid);
-                    }
-                    scheduleFastWriteLocked();
-                }
+            UidState uidState = mUidStates.get(uid);
+            if (uidState == null) {
+                return;
+            }
+
+            boolean changed = false;
+
+            // Remove any package state if such.
+            if (uidState.pkgOps != null && uidState.pkgOps.remove(packageName) != null) {
+                changed = true;
+            }
+
+            // If we just nuked the last package state check if the UID is valid.
+            if (changed && uidState.pkgOps.isEmpty()
+                    && getPackagesForUid(uid).length <= 0) {
+                mUidStates.remove(uid);
+            }
+
+            if (changed) {
+                scheduleFastWriteLocked();
             }
         }
     }
 
     public void uidRemoved(int uid) {
         synchronized (this) {
-            if (mUidOps.indexOfKey(uid) >= 0) {
-                mUidOps.remove(uid);
+            if (mUidStates.indexOfKey(uid) >= 0) {
+                mUidStates.remove(uid);
                 scheduleFastWriteLocked();
             }
         }
@@ -346,16 +396,23 @@
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
         ArrayList<AppOpsManager.PackageOps> res = null;
         synchronized (this) {
-            for (int i=0; i<mUidOps.size(); i++) {
-                HashMap<String, Ops> packages = mUidOps.valueAt(i);
-                for (Ops pkgOps : packages.values()) {
+            final int uidStateCount = mUidStates.size();
+            for (int i = 0; i < uidStateCount; i++) {
+                UidState uidState = mUidStates.valueAt(i);
+                if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()) {
+                    continue;
+                }
+                ArrayMap<String, Ops> packages = uidState.pkgOps;
+                final int packageCount = packages.size();
+                for (int j = 0; j < packageCount; j++) {
+                    Ops pkgOps = packages.valueAt(j);
                     ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
                     if (resOps != null) {
                         if (res == null) {
                             res = new ArrayList<AppOpsManager.PackageOps>();
                         }
                         AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
-                                pkgOps.packageName, pkgOps.uid, resOps);
+                                pkgOps.packageName, pkgOps.uidState.uid, resOps);
                         res.add(resPackage);
                     }
                 }
@@ -380,7 +437,7 @@
             }
             ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>();
             AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
-                    pkgOps.packageName, pkgOps.uid, resOps);
+                    pkgOps.packageName, pkgOps.uidState.uid, resOps);
             res.add(resPackage);
             return res;
         }
@@ -392,11 +449,15 @@
             if (ops != null) {
                 ops.remove(op.op);
                 if (ops.size() <= 0) {
-                    HashMap<String, Ops> pkgOps = mUidOps.get(uid);
+                    UidState uidState = ops.uidState;
+                    ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
                     if (pkgOps != null) {
                         pkgOps.remove(ops.packageName);
-                        if (pkgOps.size() <= 0) {
-                            mUidOps.remove(uid);
+                        if (pkgOps.isEmpty()) {
+                            uidState.pkgOps = null;
+                        }
+                        if (uidState.isDefault()) {
+                            mUidStates.remove(uid);
                         }
                     }
                 }
@@ -405,6 +466,113 @@
     }
 
     @Override
+    public void setUidMode(int code, int uid, int mode) {
+        if (Binder.getCallingPid() != Process.myPid()) {
+            mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                    Binder.getCallingPid(), Binder.getCallingUid(), null);
+        }
+        verifyIncomingOp(code);
+        code = AppOpsManager.opToSwitch(code);
+
+        synchronized (this) {
+            final int defaultMode = AppOpsManager.opToDefaultMode(code);
+
+            UidState uidState = getUidStateLocked(uid, false);
+            if (uidState == null) {
+                if (mode == defaultMode) {
+                    return;
+                }
+                uidState = new UidState(uid);
+                uidState.opModes = new SparseIntArray();
+                uidState.opModes.put(code, mode);
+                mUidStates.put(uid, uidState);
+                scheduleWriteLocked();
+            } else if (uidState.opModes == null) {
+                if (mode != defaultMode) {
+                    uidState.opModes = new SparseIntArray();
+                    uidState.opModes.put(code, mode);
+                    scheduleWriteLocked();
+                }
+            } else {
+                if (uidState.opModes.get(code) == mode) {
+                    return;
+                }
+                if (mode == defaultMode) {
+                    uidState.opModes.delete(code);
+                    if (uidState.opModes.size() <= 0) {
+                        uidState.opModes = null;
+                    }
+                } else {
+                    uidState.opModes.put(code, mode);
+                }
+                scheduleWriteLocked();
+            }
+        }
+
+        ArrayMap<Callback, ArraySet<String>> callbackSpecs = null;
+
+        ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+        if (callbacks != null) {
+            final int callbackCount = callbacks.size();
+            for (int i = 0; i < callbackCount; i++) {
+                Callback callback = callbacks.get(i);
+                callbackSpecs = new ArrayMap<>();
+                callbackSpecs.put(callback, null);
+            }
+        }
+
+        String[] uidPackageNames = getPackagesForUid(uid);
+        for (String uidPackageName : uidPackageNames) {
+            callbacks = mPackageModeWatchers.get(uidPackageName);
+            if (callbacks != null) {
+                if (callbackSpecs == null) {
+                    callbackSpecs = new ArrayMap<>();
+                }
+                final int callbackCount = callbacks.size();
+                for (int i = 0; i < callbackCount; i++) {
+                    Callback callback = callbacks.get(i);
+                    ArraySet<String> changedPackages = callbackSpecs.get(callback);
+                    if (changedPackages == null) {
+                        changedPackages = new ArraySet<>();
+                        callbackSpecs.put(callback, changedPackages);
+                    }
+                    changedPackages.add(uidPackageName);
+                }
+            }
+        }
+
+        if (callbackSpecs == null) {
+            return;
+        }
+
+        // There are components watching for mode changes such as window manager
+        // and location manager which are in our process. The callbacks in these
+        // components may require permissions our remote caller does not have.
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            for (int i = 0; i < callbackSpecs.size(); i++) {
+                Callback callback = callbackSpecs.keyAt(i);
+                ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i);
+                try {
+                    if (reportedPackageNames == null) {
+                        callback.mCallback.opChanged(code, null);
+                    } else {
+                        final int reportedPackageCount = reportedPackageNames.size();
+                        for (int j = 0; j < reportedPackageCount; j++) {
+                            String reportedPackageName = reportedPackageNames.valueAt(j);
+                            callback.mCallback.opChanged(code, reportedPackageName);
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Error dispatching op op change", e);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public void setMode(int code, int uid, String packageName, int mode) {
         if (Binder.getCallingPid() != Process.myPid()) {
             mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
@@ -414,6 +582,7 @@
         ArrayList<Callback> repCbs = null;
         code = AppOpsManager.opToSwitch(code);
         synchronized (this) {
+            UidState uidState = getUidStateLocked(uid, false);
             Op op = getOpLocked(code, uid, packageName, true);
             if (op != null) {
                 if (op.mode != mode) {
@@ -468,14 +637,26 @@
         if (callbacks == null) {
             callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
         }
+        boolean duplicate = false;
         for (int i=0; i<cbs.size(); i++) {
             Callback cb = cbs.get(i);
             ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
             if (reports == null) {
                 reports = new ArrayList<Pair<String, Integer>>();
                 callbacks.put(cb, reports);
+            } else {
+                final int reportCount = reports.size();
+                for (int j = 0; j < reportCount; j++) {
+                    Pair<String, Integer> report = reports.get(j);
+                    if (report.second == op && report.first.equals(packageName)) {
+                        duplicate = true;
+                        break;
+                    }
+                }
             }
-            reports.add(new Pair<String, Integer>(packageName, op));
+            if (!duplicate) {
+                reports.add(new Pair<>(packageName, op));
+            }
         }
         return callbacks;
     }
@@ -488,16 +669,54 @@
                 callingPid, callingUid, null);
         reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
                 true, true, "resetAllModes", null);
+
+        int reqUid = -1;
+        if (reqPackageName != null) {
+            try {
+                reqUid = AppGlobals.getPackageManager().getPackageUid(
+                        reqPackageName, reqUserId);
+            } catch (RemoteException e) {
+                /* ignore - local call */
+            }
+        }
+
         HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
         synchronized (this) {
             boolean changed = false;
-            for (int i=mUidOps.size()-1; i>=0; i--) {
-                HashMap<String, Ops> packages = mUidOps.valueAt(i);
+            for (int i = mUidStates.size() - 1; i >= 0; i--) {
+                UidState uidState = mUidStates.valueAt(i);
+
+                SparseIntArray opModes = uidState.opModes;
+                if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
+                    final int uidOpCount = opModes.size();
+                    for (int j = uidOpCount - 1; j >= 0; j--) {
+                        final int code = opModes.keyAt(j);
+                        if (AppOpsManager.opAllowsReset(code)) {
+                            opModes.removeAt(j);
+                            if (opModes.size() <= 0) {
+                                uidState.opModes = null;
+                            }
+                            for (String packageName : getPackagesForUid(uidState.uid)) {
+                                callbacks = addCallbacks(callbacks, packageName, code,
+                                        mOpModeWatchers.get(code));
+                                callbacks = addCallbacks(callbacks, packageName, code,
+                                        mPackageModeWatchers.get(packageName));
+                            }
+                        }
+                    }
+                }
+
+                if (uidState.pkgOps == null) {
+                    continue;
+                }
+
                 if (reqUserId != UserHandle.USER_ALL
-                        && reqUserId != UserHandle.getUserId(mUidOps.keyAt(i))) {
+                        && reqUserId != UserHandle.getUserId(uidState.uid)) {
                     // Skip any ops for a different user
                     continue;
                 }
+
+                Map<String, Ops> packages = uidState.pkgOps;
                 Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
                 while (it.hasNext()) {
                     Map.Entry<String, Ops> ent = it.next();
@@ -526,10 +745,11 @@
                         it.remove();
                     }
                 }
-                if (packages.size() == 0) {
-                    mUidOps.removeAt(i);
+                if (uidState.isDefault()) {
+                    mUidStates.remove(uidState.uid);
                 }
             }
+
             if (changed) {
                 scheduleFastWriteLocked();
             }
@@ -552,7 +772,7 @@
     @Override
     public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
         synchronized (this) {
-            op = AppOpsManager.opToSwitch(op);
+            op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
             Callback cb = mModeWatchers.get(callback.asBinder());
             if (cb == null) {
                 cb = new Callback(callback);
@@ -621,7 +841,15 @@
             if (isOpRestricted(uid, code, packageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
-            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
+            code = AppOpsManager.opToSwitch(code);
+            UidState uidState = getUidStateLocked(uid, false);
+            if (uidState != null && uidState.opModes != null) {
+                final int uidMode = uidState.opModes.get(code);
+                if (uidMode != AppOpsManager.MODE_ALLOWED) {
+                    return uidMode;
+                }
+            }
+            Op op = getOpLocked(code, uid, packageName, false);
             if (op == null) {
                 return AppOpsManager.opToDefaultMode(code);
             }
@@ -732,6 +960,17 @@
             }
             op.duration = 0;
             final int switchCode = AppOpsManager.opToSwitch(code);
+            UidState uidState = ops.uidState;
+            if (uidState.opModes != null) {
+                final int uidMode = uidState.opModes.get(switchCode);
+                if (uidMode != AppOpsManager.MODE_ALLOWED) {
+                    if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+                            + switchCode + " (" + code + ") uid " + uid + " package "
+                            + packageName);
+                    op.rejectTime = System.currentTimeMillis();
+                    return uidMode;
+                }
+            }
             final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
             if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
                 if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
@@ -766,6 +1005,17 @@
                 return AppOpsManager.MODE_IGNORED;
             }
             final int switchCode = AppOpsManager.opToSwitch(code);
+            UidState uidState = ops.uidState;
+            if (uidState.opModes != null) {
+                final int uidMode = uidState.opModes.get(switchCode);
+                if (uidMode != AppOpsManager.MODE_ALLOWED) {
+                    if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+                            + switchCode + " (" + code + ") uid " + uid + " package "
+                            + packageName);
+                    op.rejectTime = System.currentTimeMillis();
+                    return uidMode;
+                }
+            }
             final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
             if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
                 if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
@@ -847,6 +1097,18 @@
         throw new IllegalArgumentException("Bad operation #" + op);
     }
 
+    private UidState getUidStateLocked(int uid, boolean edit) {
+        UidState uidState = mUidStates.get(uid);
+        if (uidState == null) {
+            if (!edit) {
+                return null;
+            }
+            uidState = new UidState(uid);
+            mUidStates.put(uid, uidState);
+        }
+        return uidState;
+    }
+
     private Ops getOpsLocked(int uid, String packageName, boolean edit) {
         if (uid == 0) {
             packageName = "root";
@@ -857,15 +1119,19 @@
     }
 
     private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
-        HashMap<String, Ops> pkgOps = mUidOps.get(uid);
-        if (pkgOps == null) {
+        UidState uidState = getUidStateLocked(uid, edit);
+        if (uidState == null) {
+            return null;
+        }
+
+        if (uidState.pkgOps == null) {
             if (!edit) {
                 return null;
             }
-            pkgOps = new HashMap<String, Ops>();
-            mUidOps.put(uid, pkgOps);
+            uidState.pkgOps = new ArrayMap<>();
         }
-        Ops ops = pkgOps.get(packageName);
+
+        Ops ops = uidState.pkgOps.get(packageName);
         if (ops == null) {
             if (!edit) {
                 return null;
@@ -904,8 +1170,8 @@
                     Binder.restoreCallingIdentity(ident);
                 }
             }
-            ops = new Ops(packageName, uid, isPrivileged);
-            pkgOps.put(packageName, ops);
+            ops = new Ops(packageName, uidState, isPrivileged);
+            uidState.pkgOps.put(packageName, ops);
         }
         return ops;
     }
@@ -940,7 +1206,7 @@
             if (!edit) {
                 return null;
             }
-            op = new Op(ops.uid, ops.packageName, code);
+            op = new Op(ops.uidState.uid, ops.packageName, code);
             ops.put(code, op);
         }
         if (edit) {
@@ -1000,6 +1266,8 @@
                         String tagName = parser.getName();
                         if (tagName.equals("pkg")) {
                             readPackage(parser);
+                        } if (tagName.equals("uid")) {
+                            readUidOps(parser);
                         } else {
                             Slog.w(TAG, "Unknown element under <app-ops>: "
                                     + parser.getName());
@@ -1021,7 +1289,7 @@
                     Slog.w(TAG, "Failed parsing " + e);
                 } finally {
                     if (!success) {
-                        mUidOps.clear();
+                        mUidStates.clear();
                     }
                     try {
                         stream.close();
@@ -1032,6 +1300,34 @@
         }
     }
 
+    void readUidOps(XmlPullParser parser) throws NumberFormatException,
+            XmlPullParserException, IOException {
+        final int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("op")) {
+                final int code = Integer.parseInt(parser.getAttributeValue(null, "n"));
+                final int mode = Integer.parseInt(parser.getAttributeValue(null, "m"));
+                UidState uidState = getUidStateLocked(uid, true);
+                if (uidState.opModes == null) {
+                    uidState.opModes = new SparseIntArray();
+                }
+                uidState.opModes.put(code, mode);
+            } else {
+                Slog.w(TAG, "Unknown element under <uid-ops>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
     void readPackage(XmlPullParser parser) throws NumberFormatException,
             XmlPullParserException, IOException {
         String pkgName = parser.getAttributeValue(null, "n");
@@ -1114,15 +1410,16 @@
                 if (proxyPackageName != null) {
                     op.proxyPackageName = proxyPackageName;
                 }
-                HashMap<String, Ops> pkgOps = mUidOps.get(uid);
-                if (pkgOps == null) {
-                    pkgOps = new HashMap<String, Ops>();
-                    mUidOps.put(uid, pkgOps);
+
+                UidState uidState = getUidStateLocked(uid, true);
+                if (uidState.pkgOps == null) {
+                    uidState.pkgOps = new ArrayMap<>();
                 }
-                Ops ops = pkgOps.get(pkgName);
+
+                Ops ops = uidState.pkgOps.get(pkgName);
                 if (ops == null) {
-                    ops = new Ops(pkgName, uid, isPrivileged);
-                    pkgOps.put(pkgName, ops);
+                    ops = new Ops(pkgName, uidState, isPrivileged);
+                    uidState.pkgOps.put(pkgName, ops);
                 }
                 ops.put(op.op, op);
             } else {
@@ -1149,7 +1446,27 @@
                 XmlSerializer out = new FastXmlSerializer();
                 out.setOutput(stream, StandardCharsets.UTF_8.name());
                 out.startDocument(null, true);
-                out.startTag(null, "app-ops");
+                out.startTag(null, "app");
+
+                final int uidStateCount = mUidStates.size();
+                for (int i = 0; i < uidStateCount; i++) {
+                    UidState uidState = mUidStates.valueAt(i);
+                    if (uidState.opModes != null && uidState.opModes.size() > 0) {
+                        out.startTag(null, "uid");
+                        out.attribute(null, "n", Integer.toString(uidState.uid));
+                        SparseIntArray uidOpModes = uidState.opModes;
+                        final int opCount = uidOpModes.size();
+                        for (int j = 0; j < opCount; j++) {
+                            final int op = uidOpModes.keyAt(j);
+                            final int mode = uidOpModes.valueAt(j);
+                            out.startTag(null, "op");
+                            out.attribute(null, "n", Integer.toString(op));
+                            out.attribute(null, "m", Integer.toString(mode));
+                            out.endTag(null, "op");
+                        }
+                        out.endTag(null, "uid");
+                    }
+                }
 
                 if (allOps != null) {
                     String lastPkg = null;
@@ -1316,9 +1633,27 @@
             if (needSep) {
                 pw.println();
             }
-            for (int i=0; i<mUidOps.size(); i++) {
-                pw.print("  Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":");
-                HashMap<String, Ops> pkgOps = mUidOps.valueAt(i);
+            for (int i=0; i<mUidStates.size(); i++) {
+                UidState uidState = mUidStates.valueAt(i);
+
+                pw.print("  Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
+
+                SparseIntArray opModes = uidState.opModes;
+                if (opModes != null) {
+                    final int opModeCount = opModes.size();
+                    for (int j = 0; j < opModeCount; j++) {
+                        final int code = opModes.keyAt(j);
+                        final int mode = opModes.valueAt(j);
+                        pw.print("      "); pw.print(AppOpsManager.opToName(code));
+                        pw.print(": mode="); pw.println(mode);
+                    }
+                }
+
+                ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
+                if (pkgOps == null) {
+                    continue;
+                }
+
                 for (Ops ops : pkgOps.values()) {
                     pw.print("    Package "); pw.print(ops.packageName); pw.println(":");
                     for (int j=0; j<ops.size(); j++) {
@@ -1382,4 +1717,12 @@
         }
     }
 
+    private static String[] getPackagesForUid(int uid) {
+        try {
+            return AppGlobals.getPackageManager().getPackagesForUid(uid);
+        } catch (RemoteException e) {
+            /* ignore - local call */
+        }
+        return EmptyArray.STRING;
+    }
 }
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index d7b0765..e17ff5c 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -32,6 +32,7 @@
 import android.os.PowerManager.WakeLock;
 import android.os.SystemProperties;
 import android.provider.MediaStore;
+import android.provider.Settings;
 import android.util.Slog;
 
 /**
@@ -152,13 +153,25 @@
 
         private void handleCameraLaunchGesture() {
             if (DBG) Slog.d(TAG, "Received a camera launch event.");
+            boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
+                    Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+            if (!userSetupComplete) {
+                if (DBG) Slog.d(TAG, String.format(
+                        "userSetupComplete = %s, ignoring camera launch gesture.",
+                        userSetupComplete));
+                return;
+            }
+            if (DBG) Slog.d(TAG, String.format(
+                    "userSetupComplete = %s, performing camera launch gesture.",
+                    userSetupComplete));
             boolean locked = mKeyGuard != null && mKeyGuard.inKeyguardRestrictedInputMode();
             String action = locked
                     ? MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE
                     : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA;
             Intent intent = new Intent(action);
             PackageManager pm = mContext.getPackageManager();
-            ResolveInfo componentInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+            ResolveInfo componentInfo = pm.resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
             if (componentInfo == null) {
                 if (DBG) Slog.d(TAG, "Couldn't find an app to process the camera intent.");
                 return;
@@ -167,7 +180,6 @@
             if (mVibrator != null && mVibrator.hasVibrator()) {
                 mVibrator.vibrate(1000L);
             }
-
             // Turn on the screen before the camera launches.
             mWakeLock.acquire(500L);
             intent.setComponent(new ComponentName(componentInfo.activityInfo.packageName,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 95cbf10..a7cd9ff 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1257,7 +1257,11 @@
                 }
                 for (int stream = 0; stream < mStreamStates.length; stream++) {
                     if (streamTypeAlias == mStreamVolumeAlias[stream]) {
-                        mStreamStates[stream].mute(state);
+                        if (!(readCameraSoundForced()
+                                    && (mStreamStates[stream].getStreamType()
+                                        == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
+                            mStreamStates[stream].mute(state);
+                        }
                     }
                 }
             } else if ((direction == AudioManager.ADJUST_RAISE) &&
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ba46f4c..4479a37 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8604,7 +8604,7 @@
         if (!allowed) {
             if (!allowed && (bp.protectionLevel
                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
-                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.MNC) {
+                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                 // If this was a previously normal/dangerous permission that got moved
                 // to a system permission as part of the runtime permission redesign, then
                 // we still want to blindly grant it to old apps.
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a57463c..7bd0635 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -559,6 +559,7 @@
             set.addAnimation(clipAnimTB);
             set.addAnimation(translateY);
             set.addAnimation(alpha);
+            set.setZAdjustment(Animation.ZORDER_TOP);
             set.initialize(appWidth, appHeight, appWidth, appHeight);
             anim = set;
         } else {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 68bc773..af21eb3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2657,6 +2657,16 @@
         return disabled;
     }
 
+    boolean isSecureLocked(WindowState w) {
+        if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+            return true;
+        }
+        if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Set mScreenCaptureDisabled for specific user
      */
@@ -3168,6 +3178,9 @@
             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
+            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceControl != null) {
+                winAnimator.mSurfaceControl.setSecure(isSecureLocked(win));
+            }
 
             win.mRelayoutCalled = true;
             final int oldVisibility = win.mViewVisibility;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 31ee869..48f2a9d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -785,11 +785,7 @@
             int flags = SurfaceControl.HIDDEN;
             final WindowManager.LayoutParams attrs = w.mAttrs;
 
-            if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
-                flags |= SurfaceControl.SECURE;
-            }
-
-            if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
+            if (mService.isSecureLocked(w)) {
                 flags |= SurfaceControl.SECURE;
             }
 
@@ -1274,6 +1270,7 @@
         if (displayContent == null) {
             return;
         }
+        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
 
         // Need to recompute a new system decor rect each time.
         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
@@ -1283,7 +1280,6 @@
         } else if (!w.isDefaultDisplay()) {
             // On a different display there is no system decor.  Crop the window
             // by the screen boundaries.
-            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
             w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
                     displayInfo.logicalWidth - w.mCompatFrame.left,
@@ -1305,9 +1301,11 @@
             applyDecorRect(w.mDecorFrame);
         }
 
-        // By default, the clip rect is the system decor if the transformation doesn't specify one.
+        final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
         final Rect clipRect = mTmpClipRect;
-        clipRect.set((mHasClipRect) ? mClipRect : w.mSystemDecorRect);
+        // We use the clip rect as provided by the tranformation for non-fullscreen windows to
+        // avoid premature clipping with the system decor rect.
+        clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
 
         // Expand the clip rect for surface insets.
         final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1316,6 +1314,13 @@
         clipRect.right += attrs.surfaceInsets.right;
         clipRect.bottom += attrs.surfaceInsets.bottom;
 
+        if (mHasClipRect && fullscreen) {
+            // We intersect the clip rect specified by the transformation with the expanded system
+            // decor rect to prevent artifacts from drawing during animation if the transformation
+            // clip rect extends outside the system decor rect.
+            clipRect.intersect(mClipRect);
+        }
+
         // The clip rect was generated assuming (0,0) as the window origin,
         // so we need to translate to match the actual surface coordinates.
         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1e833b1..cd2885b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6436,7 +6436,7 @@
                 final ApplicationInfo ai = AppGlobals.getPackageManager()
                         .getApplicationInfo(packageName, 0, user.getIdentifier());
                 final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
-                if (targetSdkVersion < android.os.Build.VERSION_CODES.MNC) {
+                if (targetSdkVersion < android.os.Build.VERSION_CODES.M) {
                     return false;
                 }
                 final PackageManager packageManager = mContext.getPackageManager();
diff --git a/tests/VoiceInteraction/res/layout/main.xml b/tests/VoiceInteraction/res/layout/main.xml
index 0f968eb..a83d02c 100644
--- a/tests/VoiceInteraction/res/layout/main.xml
+++ b/tests/VoiceInteraction/res/layout/main.xml
@@ -26,6 +26,12 @@
         android:text="@string/start"
         />
 
+    <CheckBox android:id="@+id/secure"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/secure"
+        />
+
     <com.android.test.voiceinteraction.AsyncStructure
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index ab39f99..29ffe21 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,6 +17,7 @@
 <resources>
 
     <string name="start">Start</string>
+    <string name="secure">Secure</string>
     <string name="tree">Tree</string>
     <string name="text">Text</string>
     <string name="asyncStructure">(Async structure goes here)</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
index ee75f28..87fa91a 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
@@ -21,6 +21,8 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
 
 public class VoiceInteractionMain extends Activity {
 
@@ -30,6 +32,7 @@
 
         setContentView(R.layout.main);
         findViewById(R.id.start).setOnClickListener(mStartListener);
+        findViewById(R.id.secure).setOnClickListener(mSecureListener);
     }
 
     @Override
@@ -52,4 +55,14 @@
             showAssist(null);
         }
     };
+
+    View.OnClickListener mSecureListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (((CheckBox)v).isChecked()) {
+                getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+            } else {
+                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
+            }
+        }
+    };
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 645634f..09937bc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -74,7 +74,7 @@
     }
 
     public static String getTime(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, MNC)) {
+        if (isGreaterOrEqual(platformVersion, M)) {
             return "6:00";
         }
         if (platformVersion < GINGERBREAD) {
@@ -95,7 +95,7 @@
         if (platformVersion < LOLLIPOP_MR1) {
             return "5:00";
         }
-        if (platformVersion < MNC) {
+        if (platformVersion < M) {
             return "5:10";
         }
         // Should never happen.
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index d915e5d..cf88df4 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -669,6 +669,7 @@
         try {
             return mService.getConfiguredNetworks();
         } catch (RemoteException e) {
+            Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e);
             return null;
         }
     }
@@ -1589,6 +1590,7 @@
         try {
             return mService.buildWifiConfig(uriString, mimeType, data);
         } catch (RemoteException e) {
+            Log.w(TAG, "Caught RemoteException trying to build wifi config: " + e);
             return null;
         }
     }