Merge "Fix issue #22013372: Assist should take translationX and friends..." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 3f425a2..2d51b97 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10,10 +10,8 @@
     field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
     field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
     field public static final java.lang.String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
-    field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
     field public static final java.lang.String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
     field public static final java.lang.String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
-    field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
     field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
@@ -42,7 +40,6 @@
     field public static final java.lang.String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
     field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
     field public static final java.lang.String BODY_SENSORS = "android.permission.BODY_SENSORS";
-    field public static final java.lang.String BRICK = "android.permission.BRICK";
     field public static final java.lang.String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
     field public static final java.lang.String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
     field public static final java.lang.String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
@@ -59,33 +56,25 @@
     field public static final java.lang.String CHANGE_WIFI_MULTICAST_STATE = "android.permission.CHANGE_WIFI_MULTICAST_STATE";
     field public static final java.lang.String CHANGE_WIFI_STATE = "android.permission.CHANGE_WIFI_STATE";
     field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
-    field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
     field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
     field public static final java.lang.String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
     field public static final java.lang.String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
-    field public static final java.lang.String DEVICE_POWER = "android.permission.DEVICE_POWER";
     field public static final java.lang.String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
     field public static final java.lang.String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
     field public static final java.lang.String DUMP = "android.permission.DUMP";
     field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
     field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
     field public static final java.lang.String FLASHLIGHT = "android.permission.FLASHLIGHT";
-    field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
     field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
-    field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
     field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
-    field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
-    field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
     field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
     field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
     field public static final java.lang.String INSTALL_SHORTCUT = "com.android.launcher.permission.INSTALL_SHORTCUT";
-    field public static final java.lang.String INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW";
     field public static final java.lang.String INTERNET = "android.permission.INTERNET";
     field public static final java.lang.String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
     field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
-    field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
     field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
     field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
     field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
@@ -120,13 +109,10 @@
     field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
     field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
     field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
-    field public static final java.lang.String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
     field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
     field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
     field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
     field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
-    field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION";
-    field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
     field public static final deprecated java.lang.String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
     field public static final java.lang.String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
     field public static final java.lang.String SET_TIME = "android.permission.SET_TIME";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index cb68d74..c9853df 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -504,4 +504,5 @@
 
     void grantDefaultPermissions(int userId);
     void setCarrierAppPackagesProvider(in IPackagesProvider provider);
+    int getMountExternalMode(int uid);
 }
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index f9c50f3..7234e98 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -643,6 +643,10 @@
             }
             if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
                 argsForZygote.add("--mount-external-default");
+            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+                argsForZygote.add("--mount-external-read");
+            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+                argsForZygote.add("--mount-external-write");
             }
             argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
 
@@ -802,7 +806,12 @@
      * @hide
      */
     public static final boolean isIsolated() {
-        int uid = UserHandle.getAppId(myUid());
+        return isIsolated(myUid());
+    }
+
+    /** {@hide} */
+    public static final boolean isIsolated(int uid) {
+        uid = UserHandle.getAppId(uid);
         return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
     }
 
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index e55ae99..84a879c 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1177,6 +1177,21 @@
                     _data.recycle();
                 }
             }
+
+            @Override
+            public void remountUid(int uid) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(uid);
+                    mRemote.transact(Stub.TRANSACTION_remountUid, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
         }
 
         private static final String DESCRIPTOR = "IMountService";
@@ -1292,6 +1307,8 @@
         static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
         static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
 
+        static final int TRANSACTION_remountUid = IBinder.FIRST_CALL_TRANSACTION + 61;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1845,6 +1862,13 @@
                     reply.writeNoException();
                     return true;
                 }
+                case TRANSACTION_remountUid: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int uid = data.readInt();
+                    remountUid(uid);
+                    reply.writeNoException();
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -2154,4 +2178,6 @@
     public String getPrimaryStorageUuid() throws RemoteException;
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
             throws RemoteException;
+
+    public void remountUid(int uid) throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 9b26f24..aab68e9 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -871,6 +871,15 @@
     }
 
     /** {@hide} */
+    public void remountUid(int uid) {
+        try {
+            mMountService.remountUid(uid);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
     private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
     private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
     private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 464710b..b6fa4e4c 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -714,6 +714,27 @@
             float[] lineWidths = lineBreaks.widths;
             int[] flags = lineBreaks.flags;
 
+            final int remainingLineCount = mMaximumVisibleLineCount - mLineCount;
+            final boolean ellipsisMayBeApplied = ellipsize != null
+                    && (ellipsize == TextUtils.TruncateAt.END
+                        || (mMaximumVisibleLineCount == 1
+                                && ellipsize != TextUtils.TruncateAt.MARQUEE));
+            if (remainingLineCount < breakCount && ellipsisMayBeApplied) {
+                // Treat the last line and overflowed lines as a single line.
+                breaks[remainingLineCount - 1] = breaks[breakCount - 1];
+                // Calculate width and flag.
+                float width = 0;
+                int flag = 0;
+                for (int i = remainingLineCount - 1; i < breakCount; i++) {
+                    width += lineWidths[i];
+                    flag |= flags[i] & TAB_MASK;
+                }
+                lineWidths[remainingLineCount - 1] = width;
+                flags[remainingLineCount - 1] = flag;
+
+                breakCount = remainingLineCount;
+            }
+
             // here is the offset of the starting character of the line we are currently measuring
             int here = paraStart;
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6631f26..310b474 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5231,7 +5231,7 @@
         // ExtractEditText does not call onFocus when it is displayed, and mHasSelectionOnFocus can
         // not be set. Do the test here instead.
         if (isInExtractedMode() && hasSelection() && mEditor != null
-                && mEditor.mTextActionMode == null) {
+                && mEditor.mTextActionMode == null && isShown() && hasWindowFocus()) {
             mEditor.startSelectionActionMode();
         }
 
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index c97fdf4..197004c 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -46,8 +46,12 @@
 
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = 0;
-    /** Default user-specific external storage should be mounted. */
+    /** Default external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_DEFAULT = 1;
+    /** Read-only external storage should be mounted. */
+    public static final int MOUNT_EXTERNAL_READ = 2;
+    /** Read-write external storage should be mounted. */
+    public static final int MOUNT_EXTERNAL_WRITE = 3;
 
     private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
 
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index fa870b9..3e86fac 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -519,6 +519,10 @@
                     niceName = arg.substring(arg.indexOf('=') + 1);
                 } else if (arg.equals("--mount-external-default")) {
                     mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+                } else if (arg.equals("--mount-external-read")) {
+                    mountExternal = Zygote.MOUNT_EXTERNAL_READ;
+                } else if (arg.equals("--mount-external-write")) {
+                    mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
                 } else if (arg.equals("--query-abi-list")) {
                     abiListQuery = true;
                 } else if (arg.startsWith("--instruction-set=")) {
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 523663c..32a145c 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -23,6 +23,7 @@
 import android.content.ComponentCallbacks;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -30,6 +31,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.text.TextUtils;
 import android.util.Size;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -108,8 +110,10 @@
      * Initializes a floating toolbar.
      */
     public FloatingToolbar(Context context, Window window) {
-        mContext = Preconditions.checkNotNull(context);
-        mPopup = new FloatingToolbarPopup(window.getDecorView());
+        Preconditions.checkNotNull(context);
+        Preconditions.checkNotNull(window);
+        mContext = applyDefaultTheme(context);
+        mPopup = new FloatingToolbarPopup(mContext, window.getDecorView());
     }
 
     /**
@@ -276,6 +280,7 @@
         public static final int OVERFLOW_DIRECTION_UP = 0;
         public static final int OVERFLOW_DIRECTION_DOWN = 1;
 
+        private final Context mContext;
         private final View mParent;
         private final PopupWindow mPopupWindow;
         private final ViewGroup mContentContainer;
@@ -375,9 +380,10 @@
          * @param parent  A parent view to get the {@link android.view.View#getWindowToken()} token
          *      from.
          */
-        public FloatingToolbarPopup(View parent) {
+        public FloatingToolbarPopup(Context context, View parent) {
             mParent = Preconditions.checkNotNull(parent);
-            mContentContainer = createContentContainer(parent.getContext());
+            mContext = Preconditions.checkNotNull(context);
+            mContentContainer = createContentContainer(context);
             mPopupWindow = createPopupWindow(mContentContainer);
             mDismissAnimation = createExitAnimation(
                     mContentContainer,
@@ -415,7 +421,7 @@
 
             mContentContainer.removeAllViews();
             if (mMainPanel == null) {
-                mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow);
+                mMainPanel = new FloatingToolbarMainPanel(mContext, mOpenOverflow);
             }
             List<MenuItem> overflowMenuItems =
                     mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth));
@@ -423,7 +429,7 @@
             if (!overflowMenuItems.isEmpty()) {
                 if (mOverflowPanel == null) {
                     mOverflowPanel =
-                            new FloatingToolbarOverflowPanel(mParent.getContext(), mCloseOverflow);
+                            new FloatingToolbarOverflowPanel(mContext, mCloseOverflow);
                 }
                 mOverflowPanel.setMenuItems(overflowMenuItems);
                 mOverflowPanel.setOnMenuItemClickListener(menuItemClickListener);
@@ -540,7 +546,7 @@
          * Returns the context this popup is running in.
          */
         public Context getContext() {
-            return mContentContainer.getContext();
+            return mContext;
         }
 
         private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
@@ -562,7 +568,7 @@
                 } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
                     // There is enough space at the bottom of the content.
                     y = contentRect.bottom;
-                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) {
+                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) {
                     // Just enough space to fit the toolbar with no vertical margins.
                     y = contentRect.bottom - mMarginVertical;
                 } else {
@@ -621,7 +627,7 @@
         }
 
         private int getToolbarHeightWithVerticalMargin() {
-            return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2;
+            return getEstimatedToolbarHeight(mContext) + mMarginVertical * 2;
         }
 
         /**
@@ -1477,6 +1483,17 @@
         return animation;
     }
 
+    /**
+     * Returns a re-themed context with controlled look and feel for views.
+     */
+    private static Context applyDefaultTheme(Context originalContext) {
+        TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
+        boolean isLightTheme = a.getBoolean(0, true);
+        int themeId = isLightTheme ? R.style.Theme_Material_Light : R.style.Theme_Material;
+        a.recycle();
+        return new ContextThemeWrapper(originalContext, themeId);
+    }
+
     private static int getEstimatedToolbarHeight(Context context) {
         return context.getResources().getDimensionPixelSize(R.dimen.floating_toolbar_height);
     }
@@ -1486,18 +1503,6 @@
                 .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width);
     }
 
-    private static int getAdjustedToolbarWidth(Context context, int width) {
-        int maximumWidth = getScreenWidth(context) - 2 * context.getResources()
-                .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
-
-        if (width <= 0 || width > maximumWidth) {
-            int defaultWidth = context.getResources()
-                    .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
-            width = Math.min(defaultWidth, maximumWidth);
-        }
-        return width;
-    }
-
     /**
      * Returns the device's screen width.
      */
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 76db5d3..f7cfe0e 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -66,6 +66,8 @@
 enum MountExternalKind {
   MOUNT_EXTERNAL_NONE = 0,
   MOUNT_EXTERNAL_DEFAULT = 1,
+  MOUNT_EXTERNAL_READ = 2,
+  MOUNT_EXTERNAL_WRITE = 3,
 };
 
 static void RuntimeAbort(JNIEnv* env) {
@@ -249,38 +251,49 @@
 
 // Create a private mount namespace and bind mount appropriate emulated
 // storage for the given user.
-static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
-  if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
+static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
+        bool force_mount_namespace) {
+    // See storage config details at http://source.android.com/tech/storage/
+
+    // Create a second private mount namespace for our process
+    if (unshare(CLONE_NEWNS) == -1) {
+        ALOGW("Failed to unshare(): %s", strerror(errno));
+        return false;
+    }
+
+    // Unmount storage provided by root namespace and mount requested view
+    umount2("/storage", MNT_FORCE);
+
+    String8 storageSource;
+    if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
+        storageSource = "/mnt/runtime_default";
+    } else if (mount_mode == MOUNT_EXTERNAL_READ) {
+        storageSource = "/mnt/runtime_read";
+    } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
+        storageSource = "/mnt/runtime_write";
+    } else {
+        // Sane default of no storage visible
+        return true;
+    }
+    if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
+            NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
+        ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
+        return false;
+    }
+
+    // Mount user-specific symlink helpers into place
+    userid_t user_id = multiuser_get_user_id(uid);
+    const String8 userSource(String8::format("/mnt/user/%d", user_id));
+    if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
+        return false;
+    }
+    if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
+            NULL, MS_BIND, NULL)) == -1) {
+        ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
+        return false;
+    }
+
     return true;
-  }
-
-  // Create a second private mount namespace for our process
-  if (unshare(CLONE_NEWNS) == -1) {
-      ALOGW("Failed to unshare(): %s", strerror(errno));
-      return false;
-  }
-
-  if (mount_mode == MOUNT_EXTERNAL_NONE) {
-    return true;
-  }
-
-  // See storage config details at http://source.android.com/tech/storage/
-  userid_t user_id = multiuser_get_user_id(uid);
-
-  // Bind mount user-specific storage into place
-  const String8 source(String8::format("/mnt/user/%d", user_id));
-  const String8 target(String8::format("/storage/self"));
-
-  if (fs_prepare_dir(source.string(), 0755, 0, 0) == -1) {
-    return false;
-  }
-
-  if (TEMP_FAILURE_RETRY(mount(source.string(), target.string(), NULL, MS_BIND, NULL)) == -1) {
-    ALOGW("Failed to mount %s to %s: %s", source.string(), target.string(), strerror(errno));
-    return false;
-  }
-
-  return true;
 }
 
 static bool NeedsNoRandomizeWorkaround() {
@@ -543,7 +556,7 @@
   pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                       debug_flags, rlimits,
                                       permittedCapabilities, effectiveCapabilities,
-                                      MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
+                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                       NULL, NULL);
   if (pid > 0) {
       // The zygote process checks whether the child process has died or not.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9637cf5..2cbfae2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -335,14 +335,18 @@
         android:description="@string/permgroupdesc_contacts"
         android:priority="100" />
 
-    <!-- Allows an application to read the user's contacts data. -->
+    <!-- Allows an application to read the user's contacts data.
+        <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.READ_CONTACTS"
         android:permissionGroup="android.permission-group.CONTACTS"
         android:label="@string/permlab_readContacts"
         android:description="@string/permdesc_readContacts"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to write the user's contacts data. -->
+    <!-- Allows an application to write the user's contacts data.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.WRITE_CONTACTS"
         android:permissionGroup="android.permission-group.CONTACTS"
         android:label="@string/permlab_writeContacts"
@@ -361,14 +365,18 @@
         android:description="@string/permgroupdesc_calendar"
         android:priority="200" />
 
-    <!-- Allows an application to read the user's calendar data. -->
+    <!-- Allows an application to read the user's calendar data.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.READ_CALENDAR"
         android:permissionGroup="android.permission-group.CALENDAR"
         android:label="@string/permlab_readCalendar"
         android:description="@string/permdesc_readCalendar"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to write the user's calendar data. -->
+    <!-- Allows an application to write the user's calendar data.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.WRITE_CALENDAR"
         android:permissionGroup="android.permission-group.CALENDAR"
         android:label="@string/permlab_writeCalendar"
@@ -387,7 +395,9 @@
         android:description="@string/permgroupdesc_sms"
         android:priority="300" />
 
-    <!-- Allows an application to send SMS messages. -->
+    <!-- Allows an application to send SMS messages.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.SEND_SMS"
         android:permissionGroup="android.permission-group.SMS"
         android:label="@string/permlab_sendSms"
@@ -395,28 +405,36 @@
         android:permissionFlags="costsMoney"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to receive SMS messages. -->
+    <!-- Allows an application to receive SMS messages.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.RECEIVE_SMS"
         android:permissionGroup="android.permission-group.SMS"
         android:label="@string/permlab_receiveSms"
         android:description="@string/permdesc_receiveSms"
         android:protectionLevel="dangerous"/>
 
-    <!-- Allows an application to read SMS messages. -->
+    <!-- Allows an application to read SMS messages.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.READ_SMS"
         android:permissionGroup="android.permission-group.SMS"
         android:label="@string/permlab_readSms"
         android:description="@string/permdesc_readSms"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to receive WAP push messages. -->
+    <!-- Allows an application to receive WAP push messages.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.RECEIVE_WAP_PUSH"
         android:permissionGroup="android.permission-group.SMS"
         android:label="@string/permlab_receiveWapPush"
         android:description="@string/permdesc_receiveWapPush"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to monitor incoming MMS messages. -->
+    <!-- Allows an application to monitor incoming MMS messages.
+        <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.RECEIVE_MMS"
         android:permissionGroup="android.permission-group.SMS"
         android:label="@string/permlab_receiveMms"
@@ -433,6 +451,7 @@
          additional emergency information (if Internet access is available)
          when the alert is first received, and to delay presenting the info
          to the user until after the initial alert dialog is dismissed.
+         <p>Protection level: dangerous
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_CELL_BROADCASTS"
         android:permissionGroup="android.permission-group.SMS"
@@ -471,7 +490,9 @@
      targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
      grants your app this permission. If you don't need this permission, be sure your <a
      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-     targetSdkVersion}</a> is 4 or higher.-->
+     targetSdkVersion}</a> is 4 or higher.
+     <p>Protection level: dangerous
+     -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_sdcardRead"
@@ -490,7 +511,9 @@
          <p>Starting in API level 19, this permission is <em>not</em> required to
          read/write files in your application-specific directories returned by
          {@link android.content.Context#getExternalFilesDir} and
-         {@link android.content.Context#getExternalCacheDir}. -->
+         {@link android.content.Context#getExternalCacheDir}.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_sdcardWrite"
@@ -509,14 +532,18 @@
         android:description="@string/permgroupdesc_location"
         android:priority="400" />
 
-    <!-- Allows an app to access precise location. -->
+    <!-- Allows an app to access precise location.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
         android:permissionGroup="android.permission-group.LOCATION"
         android:label="@string/permlab_accessFineLocation"
         android:description="@string/permdesc_accessFineLocation"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an app to access approximate location. -->
+    <!-- Allows an app to access approximate location.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
         android:permissionGroup="android.permission-group.LOCATION"
         android:label="@string/permlab_accessCoarseLocation"
@@ -543,7 +570,9 @@
          targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
          grants your app this permission. If you don't need this permission, be sure your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 4 or higher. -->
+         targetSdkVersion}</a> is 4 or higher.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.READ_PHONE_STATE"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_readPhoneState"
@@ -551,7 +580,9 @@
         android:protectionLevel="dangerous" />
 
     <!-- Allows an application to initiate a phone call without going through
-        the Dialer user interface for the user to confirm the call. -->
+        the Dialer user interface for the user to confirm the call.
+        <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.CALL_PHONE"
         android:permissionGroup="android.permission-group.PHONE"
         android:permissionFlags="costsMoney"
@@ -568,7 +599,9 @@
          targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
          grants your app this permission. If you don't need this permission, be sure your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p> -->
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.READ_CALL_LOG"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_readCallLog"
@@ -585,21 +618,27 @@
          targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
          grants your app this permission. If you don't need this permission, be sure your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p>  -->
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_writeCallLog"
         android:description="@string/permdesc_writeCallLog"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to add voicemails into the system. -->
+    <!-- Allows an application to add voicemails into the system.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_addVoicemail"
         android:description="@string/permdesc_addVoicemail"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to use SIP service. -->
+    <!-- Allows an application to use SIP service.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.USE_SIP"
         android:permissionGroup="android.permission-group.PHONE"
         android:description="@string/permdesc_use_sip"
@@ -608,7 +647,9 @@
 
     <!-- Allows an application to see the number being dialed during an outgoing
          call with the option to redirect the call to a different number or
-         abort the call altogether. -->
+         abort the call altogether.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_processOutgoingCalls"
@@ -629,7 +670,9 @@
         android:description="@string/permgroupdesc_microphone"
         android:priority="600" />
 
-    <!-- Allows an application to record audio. -->
+    <!-- Allows an application to record audio.
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.RECORD_AUDIO"
         android:permissionGroup="android.permission-group.MICROPHONE"
         android:label="@string/permlab_recordAudio"
@@ -655,7 +698,9 @@
          &lt;uses-feature&gt;}</a> manifest element for <em>all</em> camera features.
          If you do not require all camera features or can properly operate if a camera
          is not available, then you must modify your manifest as appropriate in order to
-         install on devices that don't support all camera features.</p> -->
+         install on devices that don't support all camera features.</p>
+         <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.CAMERA"
         android:permissionGroup="android.permission-group.CAMERA"
         android:label="@string/permlab_camera"
@@ -676,14 +721,17 @@
         android:priority="800" />
 
     <!-- Allows an application to access data from sensors that the user uses to
-         measure what is happening inside his/her body, such as heart rate. -->
+         measure what is happening inside his/her body, such as heart rate.
+         <p>Protection level: dangerous -->
     <permission android:name="android.permission.BODY_SENSORS"
         android:permissionGroup="android.permission-group.SENSORS"
         android:label="@string/permlab_bodySensors"
         android:description="@string/permdesc_bodySensors"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an app to use fingerprint hardware. -->
+    <!-- Allows an app to use fingerprint hardware.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.USE_FINGERPRINT"
         android:permissionGroup="android.permission-group.SENSORS"
         android:label="@string/permlab_useFingerprint"
@@ -768,7 +816,9 @@
     <!-- =============================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to broadcast an Intent to set an alarm for the user. -->
+    <!-- Allows an application to broadcast an Intent to set an alarm for the user.
+         <p>Protection level: normal
+    -->
     <permission android:name="com.android.alarm.permission.SET_ALARM"
         android:label="@string/permlab_setAlarm"
         android:description="@string/permdesc_setAlarm"
@@ -779,11 +829,15 @@
     <!-- =============================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to modify and remove existing voicemails in the system -->
+    <!-- Allows an application to modify and remove existing voicemails in the system
+        <p>Protection level: system|signature
+    -->
     <permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
         android:protectionLevel="system|signature" />
 
-    <!-- Allows an application to read voicemails in the system. -->
+    <!-- Allows an application to read voicemails in the system.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
         android:protectionLevel="system|signature" />
 
@@ -792,7 +846,9 @@
     <!-- ======================================= -->
     <eat-comment />
 
-    <!-- Allows an application to access extra location provider commands -->
+    <!-- Allows an application to access extra location provider commands
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"
         android:label="@string/permlab_accessLocationExtraCommands"
         android:description="@string/permdesc_accessLocationExtraCommands"
@@ -816,7 +872,10 @@
         android:protectionLevel="signature|system" />
     <uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
 
-    <!-- Allows an application to create mock location providers for testing. -->
+    <!-- @SystemApi Allows an application to create mock location providers for testing.
+         <p>Protection level: signature
+         @hide
+    -->
     <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
         android:protectionLevel="signature" />
 
@@ -825,25 +884,33 @@
     <!-- ======================================= -->
     <eat-comment />
 
-    <!-- Allows applications to open network sockets. -->
+    <!-- Allows applications to open network sockets.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.INTERNET"
         android:description="@string/permdesc_createNetworkSockets"
         android:label="@string/permlab_createNetworkSockets"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to access information about networks -->
+    <!-- Allows applications to access information about networks
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.ACCESS_NETWORK_STATE"
         android:description="@string/permdesc_accessNetworkState"
         android:label="@string/permlab_accessNetworkState"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to access information about Wi-Fi networks -->
+    <!-- Allows applications to access information about Wi-Fi networks.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.ACCESS_WIFI_STATE"
         android:description="@string/permdesc_accessWifiState"
         android:label="@string/permlab_accessWifiState"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to change Wi-Fi connectivity state -->
+    <!-- Allows applications to change Wi-Fi connectivity state.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.CHANGE_WIFI_STATE"
         android:description="@string/permdesc_changeWifiState"
         android:label="@string/permlab_changeWifiState"
@@ -890,13 +957,17 @@
     <!-- ======================================= -->
     <eat-comment />
 
-    <!-- Allows applications to connect to paired bluetooth devices -->
+    <!-- Allows applications to connect to paired bluetooth devices.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.BLUETOOTH"
         android:description="@string/permdesc_bluetooth"
         android:label="@string/permlab_bluetooth"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to discover and pair bluetooth devices -->
+    <!-- Allows applications to discover and pair bluetooth devices.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.BLUETOOTH_ADMIN"
         android:description="@string/permdesc_bluetoothAdmin"
         android:label="@string/permlab_bluetoothAdmin"
@@ -920,7 +991,9 @@
     <permission android:name="android.permission.BLUETOOTH_STACK"
         android:protectionLevel="signature" />
 
-    <!-- Allows applications to perform I/O operations over NFC -->
+    <!-- Allows applications to perform I/O operations over NFC.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.NFC"
         android:description="@string/permdesc_nfc"
         android:label="@string/permlab_nfc"
@@ -960,10 +1033,12 @@
         android:permissionGroupFlags="personalInfo"
         android:priority="1000" />
 
-    <!-- Allows access to the list of accounts in the Accounts Service -->
+    <!-- Allows access to the list of accounts in the Accounts Service.
+        <p>Protection level: dangerous
+    -->
     <permission android:name="android.permission.GET_ACCOUNTS"
         android:permissionGroup="android.permission-group.CONTACTS"
-        android:protectionLevel="normal"
+        android:protectionLevel="dangerous"
         android:description="@string/permdesc_getAccounts"
         android:label="@string/permlab_getAccounts" />
 
@@ -978,32 +1053,42 @@
     <!-- ================================== -->
     <eat-comment />
 
-    <!-- Allows applications to enter Wi-Fi Multicast mode -->
+    <!-- Allows applications to enter Wi-Fi Multicast mode.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
         android:description="@string/permdesc_changeWifiMulticastState"
         android:label="@string/permlab_changeWifiMulticastState"
         android:protectionLevel="normal" />
 
-    <!-- Allows access to the vibrator -->
+    <!-- Allows access to the vibrator.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.VIBRATE"
         android:label="@string/permlab_vibrate"
         android:description="@string/permdesc_vibrate"
         android:protectionLevel="normal" />
 
-    <!-- Allows access to the flashlight -->
+    <!-- Allows access to the flashlight.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.FLASHLIGHT"
         android:label="@string/permlab_flashlight"
         android:description="@string/permdesc_flashlight"
         android:protectionLevel="normal" />
 
     <!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
-         from dimming -->
+         from dimming.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.WAKE_LOCK"
         android:label="@string/permlab_wakeLock"
         android:description="@string/permdesc_wakeLock"
         android:protectionLevel="normal" />
 
-    <!-- Allows using the device's IR transmitter, if available -->
+    <!-- Allows using the device's IR transmitter, if available.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.TRANSMIT_IR"
         android:label="@string/permlab_transmitIr"
         android:description="@string/permdesc_transmitIr"
@@ -1014,7 +1099,9 @@
     <!-- ==================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to modify global audio settings -->
+    <!-- Allows an application to modify global audio settings.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
         android:label="@string/permlab_modifyAudioSettings"
         android:description="@string/permdesc_modifyAudioSettings"
@@ -1036,8 +1123,10 @@
     <permission android:name="android.permission.ACCESS_MTP"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows access to hardware peripherals.  Intended only for hardware testing.
-    <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Allows access to hardware peripherals.  Intended only for hardware testing.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.HARDWARE_TEST"
         android:protectionLevel="signature" />
 
@@ -1146,7 +1235,9 @@
         android:protectionLevel="system|signature" />
 
     <!-- Must be required by a {@link android.telecom.InCallService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="android.permission.BIND_INCALL_SERVICE"
         android:protectionLevel="system|signature" />
 
@@ -1160,7 +1251,9 @@
         android:protectionLevel="system|signature" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
         android:protectionLevel="system|signature" />
 
@@ -1185,7 +1278,9 @@
         android:protectionLevel="signature|system" />
 
     <!-- Allows an application to manage access to documents, usually as part
-         of a document picker. -->
+         of a document picker.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.MANAGE_DOCUMENTS"
         android:protectionLevel="signature" />
 
@@ -1194,7 +1289,9 @@
     <!-- ================================== -->
     <eat-comment />
 
-    <!-- Allows applications to disable the keyguard if it is not secure. -->
+    <!-- Allows applications to disable the keyguard if it is not secure.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.DISABLE_KEYGUARD"
         android:description="@string/permdesc_disableKeyguard"
         android:label="@string/permlab_disableKeyguard"
@@ -1261,7 +1358,9 @@
     <permission android:name="android.permission.GET_DETAILED_TASKS"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to change the Z-order of tasks -->
+    <!-- Allows an application to change the Z-order of tasks.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.REORDER_TASKS"
         android:label="@string/permlab_reorderTasks"
         android:description="@string/permdesc_reorderTasks"
@@ -1289,7 +1388,9 @@
         android:protectionLevel="normal" />
 
     <!-- Allows an application to call
-        {@link android.app.ActivityManager#killBackgroundProcesses}. -->
+        {@link android.app.ActivityManager#killBackgroundProcesses}.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
         android:label="@string/permlab_killBackgroundProcesses"
         android:description="@string/permdesc_killBackgroundProcesses"
@@ -1320,13 +1421,17 @@
     <!-- ================================== -->
     <eat-comment />
 
-    <!-- Allows applications to set the wallpaper -->
+    <!-- Allows applications to set the wallpaper.
+         <p>Protection level: normal
+     -->
     <permission android:name="android.permission.SET_WALLPAPER"
         android:label="@string/permlab_setWallpaper"
         android:description="@string/permdesc_setWallpaper"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to set the wallpaper hints -->
+    <!-- Allows applications to set the wallpaper hints.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.SET_WALLPAPER_HINTS"
         android:label="@string/permlab_setWallpaperHints"
         android:description="@string/permdesc_setWallpaperHints"
@@ -1342,7 +1447,9 @@
     <permission android:name="android.permission.SET_TIME"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows applications to set the system time zone -->
+    <!-- Allows applications to set the system time zone.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.SET_TIME_ZONE"
         android:label="@string/permlab_setTimeZone"
         android:description="@string/permdesc_setTimeZone"
@@ -1353,7 +1460,9 @@
     <!-- ==================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to expand or collapse the status bar. -->
+    <!-- Allows an application to expand or collapse the status bar.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.EXPAND_STATUS_BAR"
         android:label="@string/permlab_expandStatusBar"
         android:description="@string/permdesc_expandStatusBar"
@@ -1364,13 +1473,17 @@
     <!-- ============================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to install a shortcut in Launcher -->
+    <!-- Allows an application to install a shortcut in Launcher.
+         <p>Protection level: normal
+    -->
     <permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
         android:label="@string/permlab_install_shortcut"
         android:description="@string/permdesc_install_shortcut"
         android:protectionLevel="normal"/>
 
-    <!-- Allows an application to uninstall a shortcut in Launcher -->
+    <!-- Allows an application to uninstall a shortcut in Launcher.
+         <p>Protection level: normal
+    -->
     <permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
         android:label="@string/permlab_uninstall_shortcut"
         android:description="@string/permdesc_uninstall_shortcut"
@@ -1381,19 +1494,25 @@
     <!-- ==================================================== -->
     <eat-comment />
 
-    <!-- Allows applications to read the sync settings -->
+    <!-- Allows applications to read the sync settings.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.READ_SYNC_SETTINGS"
         android:description="@string/permdesc_readSyncSettings"
         android:label="@string/permlab_readSyncSettings"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to write the sync settings -->
+    <!-- Allows applications to write the sync settings.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.WRITE_SYNC_SETTINGS"
         android:description="@string/permdesc_writeSyncSettings"
         android:label="@string/permlab_writeSyncSettings"
         android:protectionLevel="normal" />
 
-    <!-- Allows applications to read the sync stats -->
+    <!-- Allows applications to read the sync stats.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.READ_SYNC_STATS"
         android:description="@string/permdesc_readSyncStats"
         android:label="@string/permlab_readSyncStats"
@@ -1451,7 +1570,9 @@
         android:description="@string/permdesc_persistentActivity"
         android:protectionLevel="normal" />
 
-    <!-- Allows an application to find out the space used by any package. -->
+    <!-- Allows an application to find out the space used by any package.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.GET_PACKAGE_SIZE"
         android:label="@string/permlab_getPackageSize"
         android:description="@string/permdesc_getPackageSize"
@@ -1473,7 +1594,9 @@
          system to start and allowing applications to have themselves
          running without the user being aware of them.  As such, you must
          explicitly declare your use of this facility to make that visible
-         to the user. -->
+         to the user.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
         android:label="@string/permlab_receiveBootCompleted"
         android:description="@string/permdesc_receiveBootCompleted"
@@ -1482,7 +1605,9 @@
     <!-- Allows an application to broadcast sticky intents.  These are
          broadcasts whose data is held by the system after being finished,
          so that clients can quickly retrieve that data without having
-         to wait for the next broadcast. -->
+         to wait for the next broadcast.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.BROADCAST_STICKY"
         android:label="@string/permlab_broadcastSticky"
         android:description="@string/permdesc_broadcastSticky"
@@ -1528,14 +1653,18 @@
     <permission android:name="android.permission.WRITE_APN_SETTINGS"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows applications to change network connectivity state -->
+    <!-- Allows applications to change network connectivity state.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.CHANGE_NETWORK_STATE"
         android:description="@string/permdesc_changeNetworkState"
         android:label="@string/permlab_changeNetworkState"
         android:protectionLevel="normal" />
 
     <!-- Allows an application to clear the caches of all installed
-         applications on the device.  -->
+         applications on the device.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="android.permission.CLEAR_APP_CACHE"
         android:protectionLevel="signatureOrSystem" />
 
@@ -1634,9 +1763,11 @@
     <permission android:name="android.permission.STATUS_BAR_SERVICE"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to force a BACK operation on whatever is the
+    <!-- @SystemApi Allows an application to force a BACK operation on whatever is the
          top activity.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.FORCE_BACK"
         android:protectionLevel="signature" />
 
@@ -1654,15 +1785,19 @@
     <permission android:name="android.permission.UPDATE_APP_OPS_STATS"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows an application to open windows that are for use by parts
+    <!-- @SystemApi Allows an application to open windows that are for use by parts
          of the system user interface.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to manage (create, destroy,
+    <!-- @SystemApi Allows an application to manage (create, destroy,
          Z-order) application tokens in the window manager.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.MANAGE_APP_TOKENS"
         android:protectionLevel="signature" />
 
@@ -1671,10 +1806,12 @@
     <permission android:name="android.permission.FREEZE_SCREEN"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to inject user events (keys, touch, trackball)
+    <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
          into the event stream and deliver them to ANY window.  Without this
          permission, you can only deliver events to windows in your own process.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.INJECT_EVENTS"
         android:protectionLevel="signature" />
 
@@ -1695,10 +1832,12 @@
     <permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to watch and control how activities are
+    <!-- @SystemApi Allows an application to watch and control how activities are
          started globally in the system.  Only for is in debugging
          (usually the monkey command).
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.SET_ACTIVITY_WATCHER"
         android:protectionLevel="signature" />
 
@@ -1716,9 +1855,11 @@
     <permission android:name="android.permission.STOP_APP_SWITCHES"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows an application to retrieve private information about
+    <!-- @SystemApi Allows an application to retrieve private information about
          the current top activity, such as any assist context it can provide.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
         android:protectionLevel="signature" />
 
@@ -1730,28 +1871,38 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.inputmethodservice.InputMethodService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_INPUT_METHOD"
         android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.media.midi.MidiDeviceService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.printservice.PrintService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_PRINT_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
          or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
-         the system can bind to it. -->
+         the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_NFC_SERVICE"
         android:protectionLevel="signature" />
 
@@ -1761,22 +1912,30 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by a TextService (e.g. SpellCheckerService)
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_TEXT_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.net.VpnService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_VPN_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="android.permission.BIND_WALLPAPER"
         android:protectionLevel="signature|system" />
 
     <!-- Must be required by a {@link android.service.voice.VoiceInteractionService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_VOICE_INTERACTION"
         android:protectionLevel="signature" />
 
@@ -1793,7 +1952,9 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.media.tv.TvInputService}
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_TV_INPUT"
         android:protectionLevel="signature|system" />
 
@@ -1810,7 +1971,9 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by device administration receiver, to ensure that only the
-         system can interact with it. -->
+         system can interact with it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_DEVICE_ADMIN"
         android:protectionLevel="signature" />
 
@@ -1820,14 +1983,18 @@
     <permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows low-level access to setting the orientation (actually
+    <!-- @SystemApi Allows low-level access to setting the orientation (actually
          rotation) of the screen.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.SET_ORIENTATION"
         android:protectionLevel="signature" />
 
-    <!-- Allows low-level access to setting the pointer speed.
-         <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Allows low-level access to setting the pointer speed.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.SET_POINTER_SPEED"
         android:protectionLevel="signature" />
 
@@ -1845,7 +2012,9 @@
 
     <!-- Allows an application to request installing packages. Apps
          targeting APIs greater than 22 must hold this permission in
-         order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.-->
+         order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
         android:label="@string/permlab_requestInstallPackages"
         android:description="@string/permdesc_requestInstallPackages"
@@ -1856,8 +2025,10 @@
     <permission android:name="android.permission.INSTALL_PACKAGES"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows an application to clear user data.
-    <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Allows an application to clear user data.
+         <p>Not for use by third-party applications
+         @hide
+    -->
     <permission android:name="android.permission.CLEAR_APP_USER_DATA"
         android:protectionLevel="signature" />
 
@@ -1890,8 +2061,10 @@
     <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
         android:protectionLevel="signatureOrSystem" />
 
-    <!-- Allows an application to use SurfaceFlinger's low level features.
-    <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
         android:protectionLevel="signature" />
 
@@ -1957,8 +2130,10 @@
     <permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
         android:protectionLevel="signature|system" />
 
-    <!-- Required to be able to disable the device (very dangerous!).
-    <p>Not for use by third-party applications.. -->
+    <!-- @SystemApi Required to be able to disable the device (very dangerous!).
+         <p>Not for use by third-party applications.
+         @hide
+    -->
     <permission android:name="android.permission.BRICK"
         android:protectionLevel="signature" />
 
@@ -1967,9 +2142,11 @@
     <permission android:name="android.permission.REBOOT"
         android:protectionLevel="signature|system" />
 
-   <!-- Allows low-level access to power management.
-   <p>Not for use by third-party applications. -->
-    <permission android:name="android.permission.DEVICE_POWER"
+   <!-- @SystemApi Allows low-level access to power management.
+        <p>Not for use by third-party applications.
+        @hide
+    -->
+   <permission android:name="android.permission.DEVICE_POWER"
         android:protectionLevel="signature" />
 
    <!-- Allows access to the PowerManager.userActivity function.
@@ -1983,23 +2160,27 @@
 
     <!-- Run as a manufacturer test application, running as the root user.
          Only available when the device is running in manufacturer test mode.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+    -->
     <permission android:name="android.permission.FACTORY_TEST"
         android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a notification that an application
          package has been removed.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+    -->
     <permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
         android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast an SMS receipt notification.
-    <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+    -->
     <permission android:name="android.permission.BROADCAST_SMS"
         android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a WAP PUSH receipt notification.
-    <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+    -->
     <permission android:name="android.permission.BROADCAST_WAP_PUSH"
         android:protectionLevel="signature" />
 
@@ -2242,7 +2423,9 @@
     <permission android:name="android.permission.ACCESS_NOTIFICATIONS"
         android:protectionLevel="signature|system" />
 
-    <!-- Marker permission for applications that wish to access notification policy. -->
+    <!-- Marker permission for applications that wish to access notification policy.
+         <p>Protection level: normal
+    -->
     <permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"
         android:description="@string/permdesc_access_notification_policy"
         android:label="@string/permlab_access_notification_policy"
@@ -2286,13 +2469,17 @@
 
     <!-- Must be required by an {@link
          android.service.notification.NotificationListenerService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link
          android.service.chooser.ChooserTargetService}, to ensure that
-         only the system can bind to it. -->
+         only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
         android:protectionLevel="signature" />
 
@@ -2304,7 +2491,9 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.service.dreams.DreamService},
-         to ensure that only the system can bind to it. -->
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_DREAM_SERVICE"
         android:protectionLevel="signature" />
 
@@ -2359,7 +2548,9 @@
 
     <!-- The system process that is allowed to bind to services in carrier apps will
          have this permission. Carrier apps should use this permission to protect
-         their services that only the system is allowed to bind to. -->
+         their services that only the system is allowed to bind to.
+         <p>Protection level: system|signature
+    -->
     <permission android:name="android.permission.BIND_CARRIER_SERVICES"
         android:label="@string/permlab_bindCarrierServices"
         android:description="@string/permdesc_bindCarrierServices"
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 1b58ce5..482f91f 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -18,7 +18,8 @@
 <Button xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
-    android:minWidth="@dimen/floating_toolbar_menu_button_side_padding"
+    android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width"
+    android:minHeight="@dimen/floating_toolbar_height"
     android:paddingStart="@dimen/floating_toolbar_menu_button_side_padding"
     android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding"
     android:paddingTop="0dp"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 33c9c60..fd47d49 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -27,6 +27,9 @@
         <!-- ============== -->
         <eat-comment />
 
+        <!-- Specifies that a theme has a light background with dark text on top.  -->
+        <attr name="isLightTheme" format="boolean" />
+
         <!-- Default color of foreground imagery. -->
         <attr name="colorForeground" format="color" />
         <!-- Default color of foreground imagery on an inverted background. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3a1a156..5c42d04 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -240,6 +240,7 @@
   <java-symbol type="attr" name="windowFixedHeightMajor" />
   <java-symbol type="attr" name="windowFixedHeightMinor" />
   <java-symbol type="attr" name="accessibilityFocusedDrawable"/>
+  <java-symbol type="attr" name="isLightTheme"/>
 
   <java-symbol type="bool" name="action_bar_embed_tabs" />
   <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b7acdd4..c230645 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -42,6 +42,7 @@
     -->
     <style name="Theme">
 
+        <item name="isLightTheme">false</item>
         <item name="colorForeground">@color/bright_foreground_dark</item>
         <item name="colorForegroundInverse">@color/bright_foreground_dark_inverse</item>
         <item name="colorBackground">@color/background_dark</item>
@@ -472,6 +473,7 @@
          background will be a light color.
          <p>This is designed for API level 10 and lower.</p>-->
     <style name="Theme.Light">
+        <item name="isLightTheme">true</item>
         <item name="windowBackground">@drawable/screen_background_selector_light</item>
         <item name="windowClipToOutline">false</item>
 
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index c517201..377e6a16 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -58,21 +58,6 @@
         <group gid="log" />
     </permission>
 
-    <permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
-        <group gid="sdcard_r" />
-    </permission>
-
-    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
-        <group gid="sdcard_r" />
-        <group gid="sdcard_rw" />
-    </permission>
-
-    <permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
-        <group gid="sdcard_r" />
-        <group gid="sdcard_rw" />
-        <group gid="sdcard_all" />
-    </permission>
-
     <permission name="android.permission.WRITE_MEDIA_STORAGE" >
         <group gid="media_rw" />
     </permission>
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 f5fdf48..6bcb766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -213,7 +213,8 @@
             return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
         } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
             return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN) {
+        } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
+                && !mUnlockMethodCache.isCurrentlyInsecure()) {
             return R.drawable.lockscreen_fingerprint_draw_off_animation;
         } else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
             return R.drawable.lockscreen_fingerprint_draw_on_animation;
@@ -225,14 +226,14 @@
     private int getState() {
         boolean fingerprintRunning =
                 KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
-        if (mTransientFpError) {
+        if (mUnlockMethodCache.isCurrentlyInsecure()) {
+            return STATE_LOCK_OPEN;
+        } else if (mTransientFpError) {
             return STATE_FINGERPRINT_ERROR;
         } else if (fingerprintRunning) {
             return STATE_FINGERPRINT;
         } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
             return STATE_FACE_UNLOCK;
-        } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
-            return STATE_LOCK_OPEN;
         } else {
             return STATE_LOCKED;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ce5444e..860a6b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -634,7 +634,7 @@
 
         mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
                 R.layout.super_status_bar, null);
-        mStatusBarWindow.mService = this;
+        mStatusBarWindow.setService(this);
         mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 634270c..0e22aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -53,7 +53,7 @@
 
     private int mRightInset = 0;
 
-    PhoneStatusBar mService;
+    private PhoneStatusBar mService;
     private final Paint mTransparentSrcPaint = new Paint();
 
     public StatusBarWindowView(Context context, AttributeSet attrs) {
@@ -124,14 +124,22 @@
     }
 
     @Override
-    protected void onAttachedToWindow () {
-        super.onAttachedToWindow();
-
+    protected void onFinishInflate() {
+        super.onFinishInflate();
         mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
                 R.id.notification_stack_scroller);
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
-        mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
         mBrightnessMirror = findViewById(R.id.brightness_mirror);
+    }
+
+    public void setService(PhoneStatusBar service) {
+        mService = service;
+        mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
+    }
+
+    @Override
+    protected void onAttachedToWindow () {
+        super.onAttachedToWindow();
 
         // We really need to be able to animate while window animations are going on
         // so that activities may be started asynchronously from panel animations
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 4fe8fb9..45a7767 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -50,7 +50,9 @@
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -84,6 +86,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
@@ -675,13 +678,15 @@
     }
 
     private void handleSystemReady() {
-        resetIfReadyAndConnected();
+        synchronized (mLock) {
+            resetIfReadyAndConnectedLocked();
+        }
 
         // Start scheduling nominally-daily fstrim operations
         MountServiceIdler.scheduleIdlePass(mContext);
     }
 
-    private void resetIfReadyAndConnected() {
+    private void resetIfReadyAndConnectedLocked() {
         Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
                 + ", mDaemonConnected=" + mDaemonConnected);
         if (mSystemReady && mDaemonConnected) {
@@ -780,7 +785,9 @@
     }
 
     private void handleDaemonConnected() {
-        resetIfReadyAndConnected();
+        synchronized (mLock) {
+            resetIfReadyAndConnectedLocked();
+        }
 
         /*
          * Now that we've done our initialization, release
@@ -1600,7 +1607,7 @@
             // reset vold so we bind into new volume into place.
             if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
                 mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
-                resetIfReadyAndConnected();
+                resetIfReadyAndConnectedLocked();
             }
 
             writeSettingsLocked();
@@ -1628,7 +1635,7 @@
             }
 
             writeSettingsLocked();
-            resetIfReadyAndConnected();
+            resetIfReadyAndConnectedLocked();
         }
     }
 
@@ -1641,6 +1648,30 @@
     }
 
     @Override
+    public void remountUid(int uid) {
+        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+        waitForReady();
+
+        final int mountExternal = mPms.getMountExternalMode(uid);
+        final String mode;
+        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
+            mode = "default";
+        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+            mode = "read";
+        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+            mode = "write";
+        } else {
+            mode = "none";
+        }
+
+        try {
+            mConnector.execute("volume", "remount_uid", uid, mode);
+        } catch (NativeDaemonConnectorException e) {
+            Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e);
+        }
+    }
+
+    @Override
     public void setDebugFlags(int flags, int mask) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
@@ -1651,7 +1682,7 @@
             }
 
             writeSettingsLocked();
-            resetIfReadyAndConnected();
+            resetIfReadyAndConnectedLocked();
         }
     }
 
@@ -1688,7 +1719,7 @@
                 Slog.d(TAG, "Skipping move to/from primary physical");
                 onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
                 onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
-                resetIfReadyAndConnected();
+                resetIfReadyAndConnectedLocked();
 
             } else {
                 final VolumeInfo from = Preconditions.checkNotNull(
@@ -2022,7 +2053,7 @@
 
     @Override
     public void finishMediaUpdate() {
-        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             throw new SecurityException("no permission to call finishMediaUpdate()");
         }
         if (mUnmountSignal != null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f031694..7204a6e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,7 +18,9 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
 import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -3209,13 +3211,14 @@
 
             int uid = app.uid;
             int[] gids = null;
-            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
             if (!app.isolated) {
                 int[] permGids = null;
                 try {
                     checkTime(startTime, "startProcess: getting gids from package manager");
-                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
-                            app.userId);
+                    final IPackageManager pm = AppGlobals.getPackageManager();
+                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
+                    mountExternal = pm.getMountExternalMode(uid);
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
                 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index be1afa8..40ff3f4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
@@ -54,6 +55,7 @@
 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.PackageParser.isApkFile;
 import static android.os.Process.PACKAGE_INFO_GID;
 import static android.os.Process.SYSTEM_UID;
@@ -196,6 +198,7 @@
 import com.android.internal.content.PackageHelper;
 import com.android.internal.os.IParcelFileDescriptorFactory;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FastXmlSerializer;
@@ -208,8 +211,8 @@
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
 import com.android.server.Watchdog;
-import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.pm.PermissionsState.PermissionState;
+import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.storage.DeviceStorageMonitorInternal;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -2562,6 +2565,21 @@
         return null;
     }
 
+    @Override
+    public int getMountExternalMode(int uid) {
+        if (Process.isIsolated(uid)) {
+            return Zygote.MOUNT_EXTERNAL_NONE;
+        } else {
+            if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+                return Zygote.MOUNT_EXTERNAL_WRITE;
+            } else if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+                return Zygote.MOUNT_EXTERNAL_READ;
+            } else {
+                return Zygote.MOUNT_EXTERNAL_DEFAULT;
+            }
+        }
+    }
+
     static PermissionInfo generatePermissionInfo(
             BasePermission bp, int flags) {
         if (bp.perm != null) {
@@ -3201,6 +3219,7 @@
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
                 "grantRuntimePermission");
 
+        final int uid;
         final SettingBase sb;
 
         synchronized (mPackages) {
@@ -3216,6 +3235,7 @@
 
             enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
 
+            uid = pkg.applicationInfo.uid;
             sb = (SettingBase) pkg.mExtras;
             if (sb == null) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
@@ -3245,11 +3265,22 @@
                 } break;
             }
 
-            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
+            mOnPermissionChangeListeners.onPermissionsChanged(uid);
 
             // Not critical if that is lost - app has to request again.
             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
         }
+
+        if (READ_EXTERNAL_STORAGE.equals(name)
+                || WRITE_EXTERNAL_STORAGE.equals(name)) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                final StorageManager storage = mContext.getSystemService(StorageManager.class);
+                storage.remountUid(uid);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
     }
 
     @Override