Merge "Fix insertion handle disappearing in extract mode" into mnc-dev
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 6302521..fb81fd1 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -240,6 +240,8 @@
             as.close();
             throw new IOException("bt socket acept failed");
         }
+
+        as.mPfd = new ParcelFileDescriptor(fds[0]);
         as.mSocket = new LocalSocket(fds[0]);
         as.mSocketIS = as.mSocket.getInputStream();
         as.mSocketOS = as.mSocket.getOutputStream();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 103ee29..ceb610a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -502,9 +502,6 @@
 
     void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
     void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
-
-    int getMountExternalMode(int uid);
-
     void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
 
     boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
diff --git a/core/java/android/content/pm/IntentFilterVerificationInfo.java b/core/java/android/content/pm/IntentFilterVerificationInfo.java
index 96000dd..4dbac05 100644
--- a/core/java/android/content/pm/IntentFilterVerificationInfo.java
+++ b/core/java/android/content/pm/IntentFilterVerificationInfo.java
@@ -26,7 +26,9 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
+
 import com.android.internal.util.XmlUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -181,14 +183,28 @@
         return getStatusStringFromValue(mMainStatus);
     }
 
-    public static String getStatusStringFromValue(int val) {
-        switch (val) {
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK       : return "ask";
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS    : return "always";
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER     : return "never";
+    public static String getStatusStringFromValue(long val) {
+        StringBuilder sb = new StringBuilder();
+        switch ((int)(val >> 32)) {
+            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
+                sb.append("always : ");
+                sb.append(Long.toHexString(val & 0x00000000FFFFFFFF));
+                break;
+
+            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
+                sb.append("ask");
+                break;
+
+            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER:
+                sb.append("never");
+                break;
+
+            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
             default:
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED : return "undefined";
+                sb.append("undefined");
+                break;
         }
+        return sb.toString();
     }
 
     @Override
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 92b8055..9b28401 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -38,6 +38,7 @@
     public ArraySet<String> enabledComponents;
 
     public int domainVerificationStatus;
+    public int appLinkGeneration;
 
     public PackageUserState() {
         installed = true;
@@ -60,5 +61,6 @@
                 ? new ArraySet<>(o.enabledComponents) : null;
         blockUninstall = o.blockUninstall;
         domainVerificationStatus = o.domainVerificationStatus;
+        appLinkGeneration = o.appLinkGeneration;
     }
 }
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 579634f..19921b5 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -603,7 +603,7 @@
      * @hide only for resource preloading
      */
     public ConstantState<ColorStateList> getConstantState() {
-        if (mFactory != null) {
+        if (mFactory == null) {
             mFactory = new ColorStateListFactory(this);
         }
         return mFactory;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 9a99a46..731903c 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1918,6 +1918,7 @@
             other.mResId = mResId;
             other.mForce = mForce;
             other.mCount = mCount;
+            other.mHashCode = mHashCode;
             return other;
         }
     }
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index e7deae8..30cdfd3 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -123,7 +123,10 @@
             SensorEventQueue queue = mSensorListeners.get(listener);
             if (queue == null) {
                 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
-                queue = new SensorEventQueue(listener, looper, this);
+                final String fullClassName = listener.getClass().getEnclosingClass() != null ?
+                    listener.getClass().getEnclosingClass().getName() :
+                    listener.getClass().getName();
+                queue = new SensorEventQueue(listener, looper, this, fullClassName);
                 if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                     queue.dispose();
                     return false;
@@ -166,12 +169,17 @@
     protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
         if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
 
+        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+
         if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false;
 
         synchronized (mTriggerListeners) {
             TriggerEventQueue queue = mTriggerListeners.get(listener);
             if (queue == null) {
-                queue = new TriggerEventQueue(listener, mMainLooper, this);
+                final String fullClassName = listener.getClass().getEnclosingClass() != null ?
+                    listener.getClass().getEnclosingClass().getName() :
+                    listener.getClass().getName();
+                queue = new TriggerEventQueue(listener, mMainLooper, this, fullClassName);
                 if (!queue.addSensor(sensor, 0, 0)) {
                     queue.dispose();
                     return false;
@@ -234,7 +242,8 @@
                 }
                 // Initialize a client for data_injection.
                 if (mInjectEventQueue == null) {
-                    mInjectEventQueue = new InjectEventQueue(mMainLooper, this);
+                    mInjectEventQueue = new InjectEventQueue(mMainLooper, this,
+                            mContext.getPackageName());
                 }
             } else {
                 // If data injection is being disabled clean up the native resources.
@@ -296,10 +305,11 @@
         protected static final int OPERATING_MODE_NORMAL = 0;
         protected static final int OPERATING_MODE_DATA_INJECTION = 1;
 
-        BaseEventQueue(Looper looper, SystemSensorManager manager, int mode) {
+        BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
+            if (packageName == null) packageName = "";
             nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
                     new WeakReference<>(this), looper.getQueue(), mScratch,
-                    manager.mContext.getPackageName(), mode, manager.mContext.getOpPackageName());
+                    packageName, mode, manager.mContext.getOpPackageName());
             mCloseGuard.open("dispose");
             mManager = manager;
         }
@@ -419,8 +429,8 @@
         private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
 
         public SensorEventQueue(SensorEventListener listener, Looper looper,
-                SystemSensorManager manager) {
-            super(looper, manager, OPERATING_MODE_NORMAL);
+                SystemSensorManager manager, String packageName) {
+            super(looper, manager, OPERATING_MODE_NORMAL, packageName);
             mListener = listener;
         }
 
@@ -486,8 +496,8 @@
         private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>();
 
         public TriggerEventQueue(TriggerEventListener listener, Looper looper,
-                SystemSensorManager manager) {
-            super(looper, manager, OPERATING_MODE_NORMAL);
+                SystemSensorManager manager, String packageName) {
+            super(looper, manager, OPERATING_MODE_NORMAL, packageName);
             mListener = listener;
         }
 
@@ -540,8 +550,8 @@
     }
 
     final class InjectEventQueue extends BaseEventQueue {
-        public InjectEventQueue(Looper looper, SystemSensorManager manager) {
-            super(looper, manager, OPERATING_MODE_DATA_INJECTION);
+        public InjectEventQueue(Looper looper, SystemSensorManager manager, String packageName) {
+            super(looper, manager, OPERATING_MODE_DATA_INJECTION, packageName);
         }
 
         int injectSensorData(int handle, float[] values,int accuracy, long timestamp) {
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 84a879c..c3b098b 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -758,13 +758,15 @@
                 return _result;
             }
 
-            public StorageVolume[] getVolumeList(int userId) throws RemoteException {
+            public StorageVolume[] getVolumeList(int uid, String packageName)
+                    throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 StorageVolume[] _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
+                    _data.writeInt(uid);
+                    _data.writeString(packageName);
                     mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.createTypedArray(StorageVolume.CREATOR);
@@ -1177,21 +1179,6 @@
                     _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";
@@ -1307,8 +1294,6 @@
         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.
@@ -1622,8 +1607,9 @@
                 }
                 case TRANSACTION_getVolumeList: {
                     data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    StorageVolume[] result = getVolumeList(userId);
+                    int uid = data.readInt();
+                    String packageName = data.readString();
+                    StorageVolume[] result = getVolumeList(uid, packageName);
                     reply.writeNoException();
                     reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     return true;
@@ -1862,13 +1848,6 @@
                     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);
         }
@@ -2080,11 +2059,11 @@
     /**
      * Returns list of all mountable volumes.
      */
-    public StorageVolume[] getVolumeList(int userId) throws RemoteException;
+    public StorageVolume[] getVolumeList(int uid, String packageName) throws RemoteException;
 
     /**
      * Gets the path on the filesystem for the ASEC container itself.
-     * 
+     *
      * @param cid ASEC container ID
      * @return path to filesystem or {@code null} if it's not found
      * @throws RemoteException
@@ -2178,6 +2157,4 @@
     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/MountServiceInternal.java b/core/java/android/os/storage/MountServiceInternal.java
new file mode 100644
index 0000000..17aaef9
--- /dev/null
+++ b/core/java/android/os/storage/MountServiceInternal.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Mount service local interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class MountServiceInternal {
+
+    /**
+     * Policy that influences how external storage is mounted and reported.
+     */
+    public interface ExternalStorageMountPolicy {
+        /**
+         * Gets the external storage mount mode for the given uid.
+         *
+         * @param uid The UID for which to determine mount mode.
+         * @param packageName The package in the UID for making the call.
+         * @return The mount mode.
+         *
+         * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_NONE
+         * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_DEFAULT
+         * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_READ
+         * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_WRITE
+         */
+        public int getMountMode(int uid, String packageName);
+
+        /**
+         * Gets whether external storage should be reported to the given UID.
+         *
+         * @param uid The UID for which to determine whether it has external storage.
+         * @param packageName The package in the UID for making the call.
+         * @return Weather to report external storage.
+         * @return True to report the state of external storage, false to
+         *     report it as unmounted.
+         */
+        public boolean hasExternalStorage(int uid, String packageName);
+    }
+
+    /**
+     * Adds a policy for determining how external storage is mounted and reported.
+     * The mount mode is the most conservative result from querying all registered
+     * policies. Similarly, the reported state is the most conservative result from
+     * querying all registered policies.
+     *
+     * @param policy The policy to add.
+     */
+    public abstract void addExternalStoragePolicy(ExternalStorageMountPolicy policy);
+
+    /**
+     * Notify the mount service that the mount policy for a UID changed.
+     * @param uid The UID for which policy changed.
+     * @param packageName The package in the UID for making the call.
+     */
+    public abstract void onExternalStoragePolicyChanged(int uid, String packageName);
+
+    /**
+     * Gets the mount mode to use for a given UID as determined by consultin all
+     * policies.
+     *
+     * @param uid The UID for which to get mount mode.
+     * @param packageName The package in the UID for making the call.
+     * @return The mount mode.
+     */
+    public abstract int getExternalStorageMountMode(int uid, String packageName);
+}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f03e04e..140f317 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityThread;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.IPackageMoveObserver;
@@ -857,7 +858,9 @@
         final IMountService mountService = IMountService.Stub.asInterface(
                 ServiceManager.getService("mount"));
         try {
-            return mountService.getVolumeList(userId);
+            final String packageName = ActivityThread.currentOpPackageName();
+            final int uid = ActivityThread.getPackageManager().getPackageUid(packageName, userId);
+            return mountService.getVolumeList(uid, packageName);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -894,15 +897,6 @@
     }
 
     /** {@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/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 32f7bc9..8d603a1 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -298,14 +298,14 @@
         }
     }
 
-    public StorageVolume buildStorageVolume(Context context, int userId) {
+    public StorageVolume buildStorageVolume(Context context, int userId, boolean reportUnmounted) {
         final StorageManager storage = context.getSystemService(StorageManager.class);
 
         final boolean removable;
         final boolean emulated;
         final boolean allowMassStorage = false;
-        final String envState = getEnvironmentForState(state);
-
+        final String envState = reportUnmounted
+                ? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state);
         File userPath = getPathForUser(userId);
         if (userPath == null) {
             userPath = new File("/dev/null");
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index 4862f01..39f66a5 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -55,6 +55,12 @@
         }
     }
 
+    public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        for (int i = mLog.size() - 1; i >= 0; i--) {
+            pw.println(mLog.get(i));
+        }
+    }
+
     public static class ReadOnlyLocalLog {
         private final LocalLog mLog;
         ReadOnlyLocalLog(LocalLog log) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index d1af9dc..e3ce6f2e 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -61,8 +61,6 @@
  */
 public class AppSecurityPermissions {
 
-    public static final int WHICH_PERSONAL = 1<<0;
-    public static final int WHICH_DEVICE = 1<<1;
     public static final int WHICH_NEW = 1<<2;
     public static final int WHICH_ALL = 0xffff;
 
@@ -75,7 +73,8 @@
             = new HashMap<String, MyPermissionGroupInfo>();
     private final List<MyPermissionGroupInfo> mPermGroupsList
             = new ArrayList<MyPermissionGroupInfo>();
-    private final PermissionGroupInfoComparator mPermGroupComparator = new PermissionGroupInfoComparator();
+    private final PermissionGroupInfoComparator mPermGroupComparator =
+            new PermissionGroupInfoComparator();
     private final PermissionInfoComparator mPermComparator = new PermissionInfoComparator();
     private final List<MyPermissionInfo> mPermsList = new ArrayList<MyPermissionInfo>();
     private final CharSequence mNewPermPrefix;
@@ -85,8 +84,6 @@
         CharSequence mLabel;
 
         final ArrayList<MyPermissionInfo> mNewPermissions = new ArrayList<MyPermissionInfo>();
-        final ArrayList<MyPermissionInfo> mPersonalPermissions = new ArrayList<MyPermissionInfo>();
-        final ArrayList<MyPermissionInfo> mDevicePermissions = new ArrayList<MyPermissionInfo>();
         final ArrayList<MyPermissionInfo> mAllPermissions = new ArrayList<MyPermissionInfo>();
 
         MyPermissionGroupInfo(PermissionInfo perm) {
@@ -352,13 +349,6 @@
         }
         for (int i=0; i<strList.length; i++) {
             String permName = strList[i];
-            // If we are only looking at an existing app, then we only
-            // care about permissions that have actually been granted to it.
-            if (installedPkgInfo != null && info != installedPkgInfo) {
-                if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
-                    continue;
-                }
-            }
             try {
                 PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
                 if (tmpPermInfo == null) {
@@ -431,10 +421,6 @@
     private List<MyPermissionInfo> getPermissionList(MyPermissionGroupInfo grp, int which) {
         if (which == WHICH_NEW) {
             return grp.mNewPermissions;
-        } else if (which == WHICH_PERSONAL) {
-            return grp.mPersonalPermissions;
-        } else if (which == WHICH_DEVICE) {
-            return grp.mDevicePermissions;
         } else {
             return grp.mAllPermissions;
         }
@@ -577,15 +563,8 @@
     
     private static class PermissionGroupInfoComparator implements Comparator<MyPermissionGroupInfo> {
         private final Collator sCollator = Collator.getInstance();
-        PermissionGroupInfoComparator() {
-        }
+        @Override
         public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) {
-            if (((a.flags^b.flags)&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
-                return ((a.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) ? -1 : 1;
-            }
-            if (a.priority != b.priority) {
-                return a.priority > b.priority ? -1 : 1;
-            }
             return sCollator.compare(a.mLabel, b.mLabel);
         }
     }
@@ -628,11 +607,6 @@
                     if (pInfo.mNew) {
                         addPermToList(group.mNewPermissions, pInfo);
                     }
-                    if ((group.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
-                        addPermToList(group.mPersonalPermissions, pInfo);
-                    } else {
-                        addPermToList(group.mDevicePermissions, pInfo);
-                    }
                 }
             }
         }
@@ -652,12 +626,5 @@
             mPermGroupsList.add(pgrp);
         }
         Collections.sort(mPermGroupsList, mPermGroupComparator);
-        if (localLOGV) {
-            for (MyPermissionGroupInfo grp : mPermGroupsList) {
-                Log.i(TAG, "Group " + grp.name + " personal="
-                        + ((grp.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0)
-                        + " priority=" + grp.priority);
-            }
-        }
     }
 }
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
index 8c6b79b..7278d5c 100644
--- a/core/java/com/android/internal/logging/MetricsConstants.java
+++ b/core/java/com/android/internal/logging/MetricsConstants.java
@@ -22,6 +22,7 @@
  */
 public interface MetricsConstants {
     // These constants must match those in the analytic pipeline, do not edit.
+    // Add temporary values to the top of MetricsLogger instead.
     public static final int VIEW_UNKNOWN = 0;
     public static final int MAIN_SETTINGS = 1;
     public static final int ACCESSIBILITY = 2;
@@ -229,6 +230,29 @@
     public static final int ACTION_NOTE_CONTROLS = 204;
     public static final int ACTION_NOTE_INFO = 205;
     public static final int ACTION_APP_NOTE_SETTINGS = 206;
+    public static final int VOLUME_DIALOG = 207;
+    public static final int VOLUME_DIALOG_DETAILS = 208;
+    public static final int ACTION_VOLUME_SLIDER = 209;
+    public static final int ACTION_VOLUME_STREAM = 210;
+    public static final int ACTION_VOLUME_KEY = 211;
+    public static final int ACTION_VOLUME_ICON = 212;
+    public static final int ACTION_RINGER_MODE = 213;
+    public static final int ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
+    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
+    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
+    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
+    public static final int ACTION_BRIGHTNESS = 218;
+    public static final int ACTION_BRIGHTNESS_AUTO = 219;
+    public static final int BRIGHTNESS_DIALOG = 220;
+    public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
+    public static final int DREAMING = 222;
+    public static final int DOZING = 223;
+    public static final int OVERVIEW_ACTIVITY = 224;
+    public static final int ABOUT_LEGAL_SETTINGS = 225;
+    public static final int ACTION_SEARCH_RESULTS = 226;
+
+    // These constants must match those in the analytic pipeline, do not edit.
+    // Add temporary values to the top of MetricsLogger instead.
 
     //aliases
     public static final int DEVICEINFO_STORAGE = DEVICEINFO_MEMORY;
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 66fa8fc..cbe535f 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -26,25 +26,8 @@
  * @hide
  */
 public class MetricsLogger implements MetricsConstants {
-    public static final int VOLUME_DIALOG = 207;
-    public static final int VOLUME_DIALOG_DETAILS = 208;
-    public static final int ACTION_VOLUME_SLIDER = 209;
-    public static final int ACTION_VOLUME_STREAM = 210;
-    public static final int ACTION_VOLUME_KEY = 211;
-    public static final int ACTION_VOLUME_ICON = 212;
-    public static final int ACTION_RINGER_MODE = 213;
-    public static final int ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
-    public static final int ACTION_BRIGHTNESS = 218;
-    public static final int ACTION_BRIGHTNESS_AUTO = 219;
-    public static final int BRIGHTNESS_DIALOG = 220;
-    public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
-    public static final int DREAMING = 222;
-    public static final int DOZING = 223;
-    public static final int OVERVIEW_ACTIVITY = 224;
     // Temporary constants go here, to await migration to MetricsConstants.
+    // next value is 227;
 
     public static void visible(Context context, int category) throws IllegalArgumentException {
         if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
deleted file mode 100644
index 0a01ae9..0000000
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.android.internal.os.storage;
-
-import android.app.ProgressDialog;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.PowerManager;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.util.Slog;
-import android.view.WindowManager;
-import android.widget.Toast;
-
-import com.android.internal.R;
-
-/**
- * Takes care of unmounting and formatting external storage.
- *
- * @deprecated Please use {@link Intent#ACTION_MASTER_CLEAR} broadcast with extra
- * {@link Intent#EXTRA_WIPE_EXTERNAL_STORAGE} to wipe and factory reset, or call
- * {@link StorageManager#wipeAdoptableDisks} directly to format external storages.
- */
-public class ExternalStorageFormatter extends Service {
-    static final String TAG = "ExternalStorageFormatter";
-
-    public static final String FORMAT_ONLY = "com.android.internal.os.storage.FORMAT_ONLY";
-    public static final String FORMAT_AND_FACTORY_RESET = "com.android.internal.os.storage.FORMAT_AND_FACTORY_RESET";
-
-    public static final String EXTRA_ALWAYS_RESET = "always_reset";
-
-    public static final ComponentName COMPONENT_NAME
-            = new ComponentName("android", ExternalStorageFormatter.class.getName());
-
-    private StorageManager mStorageManager;
-
-    private PowerManager.WakeLock mWakeLock;
-
-    private ProgressDialog mProgressDialog = null;
-
-    private boolean mFactoryReset = false;
-    private boolean mAlwaysReset = false;
-    private String mReason = null;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-
-        mStorageManager = getSystemService(StorageManager.class);
-
-        mWakeLock = ((PowerManager)getSystemService(Context.POWER_SERVICE))
-                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ExternalStorageFormatter");
-        mWakeLock.acquire();
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (FORMAT_AND_FACTORY_RESET.equals(intent.getAction())) {
-            mFactoryReset = true;
-        }
-        if (intent.getBooleanExtra(EXTRA_ALWAYS_RESET, false)) {
-            mAlwaysReset = true;
-        }
-
-        mReason = intent.getStringExtra(Intent.EXTRA_REASON);
-        StorageVolume userVol = intent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
-        if (userVol == null) {
-            Slog.w(TAG, "Missing explicit storage volume; assuming default");
-            userVol = mStorageManager.getPrimaryVolume();
-        }
-
-        final String volumeId = userVol.getId();
-
-        mProgressDialog = new ProgressDialog(this);
-        mProgressDialog.setIndeterminate(true);
-        mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        mProgressDialog.setMessage(getText(R.string.progress_unmounting));
-        mProgressDialog.show();
-
-        new FormatTask(volumeId).start();
-
-        return Service.START_REDELIVER_INTENT;
-    }
-
-    private class FormatTask extends Thread {
-        private final String mVolumeId;
-
-        public FormatTask(String volumeId) {
-            mVolumeId = volumeId;
-        }
-
-        @Override
-        public void run() {
-            boolean success = false;
-            try {
-                mStorageManager.format(mVolumeId);
-                success = true;
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to format", e);
-                Toast.makeText(ExternalStorageFormatter.this,
-                        R.string.format_error, Toast.LENGTH_LONG).show();
-            }
-            if (success) {
-                if (mFactoryReset) {
-                    Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
-                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                    intent.putExtra(Intent.EXTRA_REASON, mReason);
-                    sendBroadcast(intent);
-                    // Intent handling is asynchronous -- assume it will happen soon.
-                    stopSelf();
-                    return;
-                }
-            }
-            // If we didn't succeed, or aren't doing a full factory
-            // reset, then it is time to remount the storage.
-            if (!success && mAlwaysReset) {
-                Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
-                intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                intent.putExtra(Intent.EXTRA_REASON, mReason);
-                sendBroadcast(intent);
-            } else {
-                try {
-                    mStorageManager.mount(mVolumeId);
-                } catch (Exception e) {
-                    Slog.w(TAG, "Failed to mount", e);
-                }
-            }
-            stopSelf();
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mProgressDialog != null) {
-            mProgressDialog.dismiss();
-        }
-        mWakeLock.release();
-        super.onDestroy();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f7c446b..91b6348 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2436,7 +2436,7 @@
 
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
-        android:protectionLevel="signature" />
+        android:protectionLevel="system|signature" />
 
     <!-- Allows an application to control keyguard.  Only allowed for system processes.
         @hide -->
@@ -2784,10 +2784,6 @@
             </intent-filter>
         </receiver>
 
-        <service android:name="com.android.internal.os.storage.ExternalStorageFormatter"
-            android:permission="android.permission.MASTER_CLEAR"
-            android:exported="true" />
-
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
diff --git a/core/res/res/layout/app_permission_item.xml b/core/res/res/layout/app_permission_item.xml
index 1eff3dc..383d771 100644
--- a/core/res/res/layout/app_permission_item.xml
+++ b/core/res/res/layout/app_permission_item.xml
@@ -31,7 +31,8 @@
         android:layout_height="24dp"
         android:layout_marginStart="16dp"
         android:layout_marginEnd="8dp"
-        android:scaleType="fitCenter" />
+        android:scaleType="fitCenter"
+        android:tint="@android:color/black"/>
 
     <ImageView
         android:layout_width="wrap_content"
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 5f46af5..ee1eaff 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Allows the app to control the flashlight."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"access IMS call service"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 5f46af5..ee1eaff 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Allows the app to control the flashlight."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"access IMS call service"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 5f46af5..ee1eaff 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Allows the app to control the flashlight."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"access IMS call service"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 2ba49a2..7cdabc5 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"ഫ്ലാഷ്ലൈറ്റിനെ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"നിങ്ങളുടെ ഇടപെടൽ ഇല്ലാതെ ഫോൺ നമ്പറുകളിലേക്ക് കോൾ ചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് അപ്രതീക്ഷിത നിരക്കുകൾക്കോ കോളുകൾക്കോ ഇടയാക്കാം. ഇത് അടിയന്തര നമ്പറുകളിലേക്ക് വിളിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ സ്ഥിരീകരണമില്ലാതെ കോളുകൾ ചെയ്യുന്നത് പണച്ചെലവിനിടയാക്കാം."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS കോൾ സേവനം ആക്സസ് ചെയ്യുക"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"നിങ്ങളുടെ ഇടപെടൽ ഇല്ലാതെ കോളുകൾ ചെയ്യാൻ IMS സേവനം ഉപയോഗിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ഫോൺ നിലയും ഐഡന്റിറ്റിയും റീഡുചെയ്യുക"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ഉപകരണത്തിന്റെ ഫോൺ സവിശേഷതകൾ ആക്‌സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി ഫോൺ നമ്പർ, ഉപകരണ ഐഡികൾ, ഒരു കോൾ സജീവമാണോയെന്നത്, ഒരു കോൾ കണക്റ്റുചെയ്‌ത വിദൂര നമ്പർ എന്നിവ നിർണ്ണയിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"സുഷുപ്‌തിയിലാകുന്നതിൽ നിന്ന് ടാബ്‌ലെറ്റിനെ തടയുക"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 63cbc40..705d493 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"සැණෙළිය පාලනයට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"දුරකථන අංක වෙත ඍජුවම අමතන්න"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"ඔබගේ මැදිහත් වීමක් නොමැතිව දුරකථන අංක ඇමතීමට යෙදුමට අවසර දෙන්න. මෙහි ප්‍රතිඑලය වන්නේ අනපේක්ෂිත අයකිරීම් හෝ ඇමතුම් ඇතිවීමයි. මෙයන් හදිසි අංක වලට ඇමතුම් ගැනීමට යෙදුමට අවසර නොදෙන බවට සටහන් කරගන්න. ඔබගේ අනුදැනුමක් නොමැතිව ඇමතුම් ගැනීමෙන් අනිෂ්ට යෙදුම් ඔබගේ මුදල් නිකරුණේ වැය කරයි."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS ඇමතුම් සේවාවට පිවිසෙන්න"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"ඔබේ මැදිහත්වීමකින් තොරව ඇමතුම් සිදු කිරීමට  IMS සේවාව භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"දුරකථනයේ තත්වය සහ අනන්‍යතාවය කියවීම"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"උපාංගයේ දුරකථන විශේෂාංග වෙත පිවිසීමට යෙදුමට අවසර දෙන්න. ඇමතුම සක්‍රිය වුවත් සහ ඇමතුමකින් දුරස්ථ අංකය සම්බන්ධ වුවත් දුරකථන අංකය සහ උපාංග ID හඳුනා ගැනීමට මෙම අවසරය යෙදුමට අවසර දෙයි."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ටැබ්ලටය නින්දෙන් වැළක්වීම"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index fa0c76d..1bc1cab 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -354,10 +354,8 @@
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Ivumela uhlelo lokusebenza ukulawula ukukhanya kwefuleshi."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"ngokuqondile shayela izinombolo zocingo"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Ivumela uhlelo lokusebenza ukushayela izinombolo zefoni ngaphandle kokuhlanganyela kwakho. Lokhu kungaholela emashajini noma amakholi angalindelekile. Qaphela ukuthi lokhu akuvumeli uhlelo lokusebenza ukushayela izinombolo zesimo esiphuthumayo. Izinhlelo zokusebenza ezingalungile zingabiza imali ngokwenze amakholi ngaphandle kokuqinisekisa kwakho."</string>
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"finyelela kusevisi yekholi ye-IMS"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Ivumela uhlelo lokusebenza ukuthi lusebenzise isevisi ye-IMS ukuze yenze amakholi ngaphandle kokungenelela kwakho."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"funda isimo sefoni kanye nesazisi"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ivumela uhlelo lokusebenza ukufinyelela izici zefoni zedivayisi. Le mvume ivumela uhlelo lokusebenza ukucacisa inombolo yefoni nobunikazi bedivayisi, ukuthi noma ikholi iyasebenza, futhi nenombolo yesilawuli kude zixhunywe ngekholi."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"gwema ithebhulethi ukuba ingalali"</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a6c4fcc..35c1f0e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3168,33 +3168,11 @@
     <!-- Label for the "Done" button on the far left of action mode toolbars. -->
     <string name="action_mode_done">Done</string>
 
-    <!-- Strings for ExternalStorageFormatter service. -->
-    <!-- Text for progress dialog while unmounting USB storage volume [CHAR LIMIT=NONE] -->
-    <string name="progress_unmounting" product="nosdcard">Unmounting USB storage\u2026</string>
-    <!-- Text for progress dialog while unmounting SD card [CHAR LIMIT=NONE] -->
-    <string name="progress_unmounting" product="default">Unmounting SD card\u2026</string>
+    <!-- Strings for MasterClearReceiver. -->
     <!-- Text for progress dialog while erasing USB storage volume [CHAR LIMIT=NONE] -->
     <string name="progress_erasing" product="nosdcard">Erasing USB storage\u2026</string>
     <!-- Text for progress dialog while erasing SD card [CHAR LIMIT=NONE] -->
     <string name="progress_erasing" product="default">Erasing SD card\u2026</string>
-    <!-- Text for message to user that an error happened when formatting USB storage [CHAR LIMIT=NONE] -->
-    <string name="format_error" product="nosdcard">Couldn\'t erase USB storage.</string>
-    <!-- Text for message to user that an error happened when formatting SD card [CHAR LIMIT=NONE] -->
-    <string name="format_error" product="default">Couldn\'t erase SD card.</string>
-    <!-- Text for message to user that SD card has been removed while in use [CHAR LIMIT=NONE] -->
-    <string name="media_bad_removal">SD card was removed before being unmounted.</string>
-    <!-- Text for message to user USB storage is currently being checked [CHAR LIMIT=NONE] -->
-    <string name="media_checking" product="nosdcard">USB storage is currently being checked.</string>
-    <!-- Text for message to user SD card is currently being checked [CHAR LIMIT=NONE] -->
-    <string name="media_checking" product="default">SD card is currently being checked.</string>
-    <!-- Text for message to user SD card has been removed [CHAR LIMIT=NONE] -->
-    <string name="media_removed">SD card has been removed.</string>
-    <!-- Text for message to user USB storage is currently mounted on a computer [CHAR LIMIT=NONE] -->
-    <string name="media_shared" product="nosdcard">USB storage is currently in use by a computer.</string>
-    <!-- Text for message to user SD card is currently mounted on a computer [CHAR LIMIT=NONE] -->
-    <string name="media_shared" product="default">SD card is currently in use by a computer.</string>
-    <!-- Text for message for an unknown external media state [CHAR LIMIT=NONE] -->
-    <string name="media_unknown_state">External media in unknown state.</string>
 
     <!-- Text for WebView's text selection Action Mode -->
     <!-- ActionBar action to share the current selection [CHAR LIMIT=10] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fcdaba2..d41031c 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -627,7 +627,6 @@
   <java-symbol type="string" name="eventTypeOther" />
   <java-symbol type="string" name="fileSizeSuffix" />
   <java-symbol type="string" name="force_close" />
-  <java-symbol type="string" name="format_error" />
   <java-symbol type="string" name="gadget_host_error_inflating" />
   <java-symbol type="string" name="gigabyteShort" />
   <java-symbol type="string" name="gpsNotifMessage" />
@@ -711,11 +710,6 @@
   <java-symbol type="string" name="lockscreen_emergency_call" />
   <java-symbol type="string" name="lockscreen_return_to_call" />
   <java-symbol type="string" name="low_memory" />
-  <java-symbol type="string" name="media_bad_removal" />
-  <java-symbol type="string" name="media_checking" />
-  <java-symbol type="string" name="media_removed" />
-  <java-symbol type="string" name="media_shared" />
-  <java-symbol type="string" name="media_unknown_state" />
   <java-symbol type="string" name="megabyteShort" />
   <java-symbol type="string" name="midnight" />
   <java-symbol type="string" name="mismatchPin" />
@@ -814,7 +808,6 @@
   <java-symbol type="string" name="print_service_installed_title" />
   <java-symbol type="string" name="print_service_installed_message" />
   <java-symbol type="string" name="progress_erasing" />
-  <java-symbol type="string" name="progress_unmounting" />
   <java-symbol type="string" name="mobile_provisioning_apn" />
   <java-symbol type="string" name="mobile_provisioning_url" />
   <java-symbol type="string" name="quick_contacts_not_available" />
diff --git a/docs/html/about/versions/android-5.0-changes.jd b/docs/html/about/versions/android-5.0-changes.jd
index f51af40..25d253f 100644
--- a/docs/html/about/versions/android-5.0-changes.jd
+++ b/docs/html/about/versions/android-5.0-changes.jd
@@ -598,3 +598,8 @@
 URI specifying where the photo should be stored. The camera app can write the
 image to the location specified by that URI, and the app that fired the intent
 would be able to read that file, even if the app is on the other profile. </p>
+
+<h3>Lockscreen widget support removed</h3>
+
+<p>Android 5.0 removes support for lockscreen widgets; it continues to support
+widgets on the home screen.</p>
\ No newline at end of file
diff --git a/docs/html/guide/components/bound-services.jd b/docs/html/guide/components/bound-services.jd
index 4215f0f2..c2ac607 100644
--- a/docs/html/guide/components/bound-services.jd
+++ b/docs/html/guide/components/bound-services.jd
@@ -649,8 +649,7 @@
 <p>Additionally, if your service is started and accepts binding, then when the system calls
 your {@link android.app.Service#onUnbind onUnbind()} method, you can optionally return
 {@code true} if you would like to receive a call to {@link android.app.Service#onRebind
-onRebind()} the next time a client binds to the service (instead of receiving a call to {@link
-android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind
+onRebind()} the next time a client binds to the service. {@link android.app.Service#onRebind
 onRebind()} returns void, but the client still receives the {@link android.os.IBinder} in its
 {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback.
 Below, figure 1 illustrates the logic for this kind of lifecycle.</p>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index a783ad1..c9575e0 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -26,12 +26,6 @@
         </ol>
       </li>
       <li><a href="#preview">Setting a Preview Image</a></li>
-      <li><a href="#lockscreen">Enabling App Widgets on the Lockscreen</a>
-        <ol>
-          <li><a href="#lockscreen-sizing">Sizing guidelines</a></li>
-        </ol>
-      </li>
-
       <li><a href="#collections">Using App Widgets with Collections</a>
         <ol>
           <li><a href="#collection_sample">Sample application</a></li>
@@ -175,8 +169,7 @@
     android:initialLayout="@layout/example_appwidget"
     android:configure="com.example.android.ExampleAppWidgetConfigure" 
     android:resizeMode="horizontal|vertical"
-    android:widgetCategory="home_screen|keyguard"
-    android:initialKeyguardLayout="@layout/example_keyguard">
+    android:widgetCategory="home_screen">
 &lt;/appwidget-provider>
 </pre>
 
@@ -281,17 +274,11 @@
 the widget can be resized. This field has no effect if it is greater than {@code minWidth} or if
 horizontal resizing isn't enabled (see <code>resizeMode</code>). Introduced in Android 4.0.</li>
 
-<li>The <code>widgetCategory</code> attribute declares whether your App Widget can be displayed on the home screen, 
-the lock screen (keyguard), or both. Values for this attribute include "home_screen" and "keyguard".  A widget that 
-is displayed on both needs to ensure that it follows the design guidelines for both widget classes. For more
-information, see <a href="#lockscreen">Enabling App Widgets on the Lockscreen</a>. The default value is "home_screen". Introduced in Android 4.2.
-</li>
-
-<li>The <code>initialKeyguardLayout</code> attribute points to the layout resource
-that defines the lock screen App Widget layout. This works the same way as the 
-{@link android.appwidget.AppWidgetProviderInfo#initialLayout android:initialLayout}, 
-in that it provides a layout that can appear immediately until your app widget is initialized and able to update 
-the layout. Introduced in Android 4.2.</li>
+<li>The <code>widgetCategory</code> attribute declares whether your App Widget
+can be displayed on the home screen ({@code home_screen}), the lock screen
+({@code keyguard}), or both. Only Android versions lower than 5.0 support
+lock-screen widgets. For Android 5.0 and higher, only {@code home_screen} is
+valid.</li>
 
 </ul>
 
@@ -737,66 +724,6 @@
 application and set it up how you'd like your preview image to appear, then save
 it and place it in your application's drawable resources.</p>
 
-<h2 id="lockscreen">Enabling App Widgets on the Lockscreen</h2>
-
-<p>Android 4.2 introduces the ability for users to add widgets to the lock screen. To indicate that your app widget is available for use on the lock screen, declare the {@link android.appwidget.AppWidgetProviderInfo#widgetCategory android:widgetCategory} attribute in the XML file that specifies your {@link android.appwidget.AppWidgetProviderInfo}. This attribute supports two values: "home_screen" and "keyguard". An app widget can declare support for one or both.</p>
-
-<p>By default, every app widget supports placement on the Home screen, so "home_screen" is the default value for the 
-{@link android.appwidget.AppWidgetProviderInfo#widgetCategory android:widgetCategory} attribute. If you want your app widget to be available for the lock screen, add the "keyguard" value:</p>
-<pre>
-&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-   ...
-   android:widgetCategory="keyguard|home_screen">
-&lt;/appwidget-provider>
-</pre>
-
-<p>If you declare a widget to be displayable on both keyguard (lockscreen) and home, it's likely that you'll want to customize the widget depending on where it is displayed. For example, you might create a separate layout file for keyguard vs. home. The next step is to detect the widget category at runtime and respond accordingly. 
-
-You can detect whether your widget is on the lockscreen or home screen by calling 
-{@link android.appwidget.AppWidgetManager#getAppWidgetOptions getAppWidgetOptions()} 
-to get the widget's options as a {@link android.os.Bundle}. The returned bundle will include the key 
-{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_HOST_CATEGORY}, whose value will be one of {@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or 
-{@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}. This value is determined by the host into which the widget is bound. In the {@link android.appwidget.AppWidgetProvider}, you can then check the widget's category, for example:</p>
-
-<pre>
-AppWidgetManager appWidgetManager;
-int widgetId;
-Bundle myOptions = appWidgetManager.getAppWidgetOptions (widgetId);
-
-// Get the value of OPTION_APPWIDGET_HOST_CATEGORY
-int category = myOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
-
-// If the value is WIDGET_CATEGORY_KEYGUARD, it's a lockscreen widget
-boolean isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
-</pre>
-
-<p>Once you know the widget's category, you can optionally load a different base layout, set different properties, and so on. For example:</p>
-
-<pre>
-int baseLayout = isKeyguard ? R.layout.keyguard_widget_layout : R.layout.widget_layout;
-</pre>
-
-
-<p>You should also specify an initial layout for your app widget when on the lock screen with the 
-{@link android.appwidget.AppWidgetProviderInfo#initialKeyguardLayout android:initialKeyguardLayout} attribute. This works the same way as the 
-{@link android.appwidget.AppWidgetProviderInfo#initialLayout android:initialLayout}, in that it provides a layout that can appear immediately until your app widget is initialized and able to update the layout.</p>
-
-<h3 id="lockscreen-sizing">Sizing guidelines</h3>
-
-<p>When a widget is hosted on the lockscreen, the framework ignores the {@code minWidth}, {@code minHeight}, {@code minResizeWidth}, and {@code minResizeHeight} fields. If a widget is also a home screen widget, these parameters are still needed as they're still used on home, but they will be ignored for purposes of the lockscreen.</p>
-
-<p>The width of a lockscreen widget always fills the provided space. For the height of a lockscreen widget, you have the following options:</p>
-
-<ul>
-    <li>If the widget does not mark itself as vertically resizable ({@code android:resizeMode="vertical"}), then the widget height will always be "small":
-      <ul>
-        <li>On a phone in portrait mode, "small" is defined as the space remaining when an unlock UI is being displayed.</li>
-        <li>On tablets and landscape phones, "small" is set on a per-device basis.</li>    
-      </ul>
-    </li>
-    <li>If the widget marks itself as vertically resizable, then the widget height shows up as "small" on portrait phones displaying an unlock UI. In all other cases, the widget sizes to fill the available height.</li>
-</ul>
-
 <h2 id="collections">Using App Widgets with Collections</h2>
 
 <p>Android 3.0 introduces app widgets with collections. These kinds of App
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index 75b3c528..4300b43 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -120,14 +120,16 @@
 &lt;uses-permission
         android:name="android.permission.USE_FINGERPRINT" /&gt;
 </pre>
-
 <img src="{@docRoot}preview/images/fingerprint-screen.png"
 srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x"
 style="float:right; margin:0 0 10px 20px" width="282" height="476" />
 
 <p>To see an app implementation of fingerprint authentication, refer to the
 <a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
-  Fingerprint Dialog sample</a>.</p>
+  Fingerprint Dialog sample</a>. For a demonstration of how you can use these authentication
+  APIs in conjunction with other Android APIs, see the video
+  <a class="video-shadowbox-button" href="https://www.youtube.com/watch?v=VOn7VrTRlA4">
+  Fingerprint and Payment APIs</a>.</p>
 
 <p>If you are testing this feature, follow these steps:</p>
 <ol>
diff --git a/docs/html/tools/debugging/ddms.jd b/docs/html/tools/debugging/ddms.jd
index 28ad11e..becbdb1 100644
--- a/docs/html/tools/debugging/ddms.jd
+++ b/docs/html/tools/debugging/ddms.jd
@@ -22,28 +22,23 @@
                 <li><a href="#logcat">Using LogCat</a></li>
                 <li><a href="#ops-location">Emulating phone operations and location</a></li>
             </ol>
-        
+
         </li>
       </ol>
     </div>
   </div>
 
-  <p>Android ships with a debugging tool called the Dalvik Debug Monitor Server (DDMS), which
+  <p>Android Studio includes a debugging tool called the Dalvik Debug Monitor Server (DDMS), which
   provides port-forwarding services, screen capture on the device, thread and heap information on
   the device, logcat, process, and radio state information, incoming call and SMS spoofing,
   location data spoofing, and more. This page provides a modest discussion of DDMS features; it is
   not an exhaustive exploration of all the features and capabilities.</p>
-  
+
   <h2 id="running">Running DDMS</h2>
-  <p>DDMS is integrated into Eclipse and is also shipped in the <code>tools/</code> directory of the
-  SDK. DDMS works with both the emulator and a connected device. If both are connected and running simultaneously, 
-  DDMS defaults to the emulator.</p>
-  
-  <ul>
-    <li>From Eclipse: Click <strong>Window > Open Perspective > Other... > DDMS</strong>.</li>
-    <li>From the command line: Type <code>ddms</code> (or <code>./ddms</code> on Mac/Linux) from the <code>tools/</code>
-    directory. </li>
-  </ul>
+  <p>DDMS is integrated into Android Studio. To use it, launch the
+  <a href="{@docRoot}tools/help/monitor.html">Android Device Monitor</a>, and click the
+  <strong>DDMS</strong> menu button. DDMS works with both the emulator and a
+  connected device. If both are connected and running simultaneously, DDMS defaults to the emulator.</p>
 
 
   <h2 id="how-ddms-works">How DDMS Interacts with a Debugger</h2>
@@ -70,7 +65,7 @@
   all the VMs on a device. The traffic that is forwarded is determined by the currently selected process
   in the DDMS Devices view.</p>
 
-  <p>The following screenshot shows a typical DDMS screen in Eclipse. If you are starting DDMS from
+  <p>The following screenshot shows a typical DDMS screen. If you are starting DDMS from
   the command line, the screen is slightly different, but much of the functionality is identical.
   Notice that the highlighted process, <code>com.android.email</code>, that is running in the emulator
   has the debugging port 8700 assigned to it as well as 8606. This signifies that DDMS is currently
@@ -78,10 +73,10 @@
 
   <img src="{@docRoot}images/debug-ddms.png"
        width="1024" />
-  <p class="img-caption"><strong>Figure 1.</strong> 
-  Screenshot of DDMS</p> 
+  <p class="img-caption"><strong>Figure 1.</strong>
+  Screenshot of DDMS</p>
 
-  <p>If you are not using Eclipse and ADT, read <a href=
+  <p>If you are using the command line, read <a href=
   "{@docRoot}tools/debugging/debugging-projects-cmdline.html#debuggingPort">Configuring
   your IDE to attach to the debugging port</a>, for more information on attaching your
   debugger.</p>
@@ -97,11 +92,11 @@
 
   <h2 id="using-ddms">Using DDMS</h2>
   The following sections describe how to use DDMS and the various tabs and panes that are part of the
-  DDMS GUI. The Eclipse version and the command line version have minor UI differences, but the 
-  same functionality. For information on running DDMS, see the previous section in this document,
+  DDMS GUI. The Android Studio version and the command line version have minor UI differences, but
+  the same functionality. For information on running DDMS, see the previous section in this document,
   <a href="#running">Running DDMS</a>.
-  
-  
+
+
   <h3 id="heap">Viewing heap usage for a process</h3>
 
   <p>DDMS allows you to view how much heap memory a process is using. This information is useful in
@@ -129,7 +124,7 @@
   objects are being allocated when you perform certain actions in your application. This
   information is valuable for assessing memory usage that can affect application performance.
   </p>
-  
+
   <p>To track memory allocation of objects:</p>
   <ol>
     <li>In the Devices tab, select the process that you want to enable allocation tracking
@@ -155,7 +150,7 @@
   <p>DDMS provides a File Explorer tab that allows you to view, copy, and delete files on the
   device. This feature is useful in examining files that are created by your application or if you
   want to transfer files to and from the device.</p>
-  
+
   <p>To work with an emulator or device's file system:</p>
   <ol>
     <li>In the Devices tab, select the emulator that you want to view the file system for.</li>
@@ -166,7 +161,7 @@
     <li>To copy a file to the device, click the <strong>Push file</strong> button on the File
     Explorer tab.</li>
   </ol>
-  
+
   <!-- Need to elaborate more on where things are stored in the file system,
    databases, apks, user info, files that are important to look at -->
 
@@ -189,7 +184,7 @@
   where profiling data is collected, use the {@link android.os.Debug#startMethodTracing()} and 
   {@link android.os.Debug#stopMethodTracing()} methods. For more information about generating trace logs, see 
   <a href="debugging-tracing.html">Profiling and Debugging UIs</a>.</p>
-  
+
   <p>Before you start method profiling in DDMS, be aware of the following restrictions:</p>
     <ul>
       <li>Android 2.1 and earlier devices must
@@ -197,7 +192,7 @@
       <li>Android 2.2 and later devices do not need an SD card. The trace log files are 
       streamed directly to your development machine.</li>
     </ul>
-  
+
   <p>To start method profiling:</p>
   <ol>
     <li>On the Devices tab, select the process that you want to enable method profiling for.</li>
@@ -218,7 +213,7 @@
   </ol>
 
    <h3 id="network">Using the Network Traffic tool</h3>
-   
+
    <p>In Android 4.0, the DDMS (Dalvik Debug Monitor Server) includes a Detailed
 Network Usage tab that makes it possible to track when your application is
 making network requests. Using this tool, you can monitor how and when your app
@@ -274,7 +269,7 @@
 
 <p>Socket tagging is supported in Android 4.0, but real-time stats will only be
 displayed on devices running Android 4.0.3 or higher.</p>
-   
+
   <h3 id="logcat">Using LogCat</h3>
 
   <p>LogCat is integrated into DDMS, and outputs the messages that you print out using the {@link android.util.Log}
@@ -296,7 +291,7 @@
 
     <li>Error</li>
   </ul>
-  
+
   <p>You can also setup your own custom filter to specify more details such as filtering messages
   with the log tags or with the process id that generated the log message. The add filter,
   edit filter, and delete filter buttons let you manage your custom filters.</p>
@@ -351,7 +346,7 @@
 
     <li>KML - Keyhole Markup Language file</li>
   </ul>
-  
+
   For more information about providing mock location data, see 
   <a href="{@docRoot}guide/topics/location/strategies.html#MockData">Location Strategies</a>.
   
diff --git a/docs/html/tools/debugging/debugging-tracing.jd b/docs/html/tools/debugging/debugging-tracing.jd
index fa5b4e1..829c82a 100644
--- a/docs/html/tools/debugging/debugging-tracing.jd
+++ b/docs/html/tools/debugging/debugging-tracing.jd
@@ -177,12 +177,15 @@
 
   <h2 id="runningtraceview">Viewing Trace Files in Traceview</h2>
 
-  <p>To run Traceview and view the trace files, enter <code>traceview
-  &lt;trace-base-name&gt;</code>. For example, to run Traceview on the example files copied in the
-  previous section, use:</p>
-  <pre>
-traceview /tmp/calc
-</pre>
+  <p>To run Traceview and view the trace files:</p>
+  <ul>
+    <li>start the
+    <a href="{@docRoot}tools/help/monitor.html">Android Device Monitor</a>. </li>
+    <li>In the Android Device Monitor tool bar, click <strong>DDMS</strong> and select a process. </li>
+    <li>Click the <strong>Start Method Profiling</strong> icon to start method profiling. </li>
+    <li>After the profiling is complete, click the <strong>Stop Method Profiling</strong> icon to
+    display the traceview. </li>
+   </ul> 
 
   <p class="note"><strong>Note:</strong> If you are trying to view the trace logs of an application 
   that is built with ProGuard enabled (release mode build), some method and member names might be obfuscated.
diff --git a/docs/html/tools/help/monitor.jd b/docs/html/tools/help/monitor.jd
index 513eb10..5f7b5ce 100644
--- a/docs/html/tools/help/monitor.jd
+++ b/docs/html/tools/help/monitor.jd
@@ -15,8 +15,8 @@
 
 <p>Android Device Monitor is a stand-alone tool that provides a graphical user interface for
 several Android application debugging and analysis tools. The Monitor tool does not
-require installation of an integrated development environment, such as Eclipse, and encapsulates the
-following tools:</p>
+require installation of an integrated development environment, such as Android Studio, and
+encapsulates the following tools:</p>
 
 <ul>
   <li><a href="{@docRoot}tools/debugging/ddms.html">DDMS</a></li>
@@ -30,9 +30,19 @@
 
 <h2 id="usage">Usage</h2>
 
-<p>To start Device Monitor, enter the following command from the SDK <code>tools/</code>
-directory:</p>
+<p>To start Device Monitor:</p>
+
+<ul>
+  <li>From Android Studio, choose <strong>Tools &gt; Android Device Monitor</strong> or click
+    the Android Device Monitor icon
+    <img src="{@docRoot}images/tools/hierarchicalviewer-icon.png" alt=""/>.
+  </li>
+  <li>From the command line, in the SDK <code>tools/</code> directory, enter the following command:
   <pre>monitor</pre>
+  </li>
+</ul>
+
+
 
 <p>Start an Android emulator or connect an Android device via USB cable, and connect Device
 Monitor to the device by selecting it in the <strong>Devices</strong> window.</p>
diff --git a/docs/html/tools/help/traceview.jd b/docs/html/tools/help/traceview.jd
index 6555ac0..a2682913 100644
--- a/docs/html/tools/help/traceview.jd
+++ b/docs/html/tools/help/traceview.jd
@@ -3,14 +3,26 @@
 parent.link=index.html
 @jd:body
 
-<p>Traceview is a graphical viewer for execution logs saved by your application. 
+<p>Traceview is a graphical viewer for execution logs saved by your application.
 Traceview can help you debug your application and profile its performance.</p>
 
-<p>To start Traceview, enter the following command from the SDK <code>tools/</code> directory:</p>
-  <pre>traceview</pre>
-</ol>
+<p>To start the Traceview tool:</p>
 
-<p>For more information on how to use Traceview, see 
-<a href="{@docRoot}tools/debugging/debugging-tracing.html">Profiling with Traceview and dmtracedump</a>
+<ul>
+ <li>Start the <a href="{@docRoot}tools/help/monitor.html">Android Device Monitor</a>. </li>
+ <li>In the Android Device Monitor tool bar, click <strong>DDMS</strong> and select a process. </li>
+ <li>Click the <strong>Start Method Profiling</strong> icon to start method profiling. </li>
+ <li>After the profiling is complete, click the <strong>Stop Method Profiling</strong> icon to
+   display the traceview. </li>
+</ul>
+
+
+<p>For more information on how to use Traceview, see
+<a href="{@docRoot}tools/debugging/debugging-tracing.html">Profiling with Traceview and
+dmtracedump</a>.
 </p>
 
+<p class="note"><strong>Note:</strong> Running <code>traceview</code> from the command line
+has been deprecated. </p>
+
+
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index a378096..2b190b4 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -262,14 +262,16 @@
 
 <h2 id="advertising">Provide Effective Advertising</h2>
 
-<p>Advertising on Android TV must always be full-screen. Ads must not appear alongside or over
-content. The user must be able to dismiss an advertisement with the D-pad controller. Video ads must
-be dismissible within 30 seconds of their start time.</p>
+<p>For the living room environment, we recommend you use video ads solutions
+that are full-screen and dismissable within 30 seconds. Functionality for
+advertising on Android TV, such as dismiss buttons and clickthroughs, must be
+accessible using the D-pad rather than touch.</p>
 
-<p>Android TV does not provide a web browser. Your ads must not attempt to launch a web browser or
-redirect to the Google Play Store.</p>
+<p>Android TV does not provide a web browser. Your ads must not attempt to
+launch a web browser or redirect to Google Play Store content that is not
+approved for Android TV devices.</p>
 
 <p class="note">
-  <strong>Note:</strong> You can use the {@link android.webkit.WebView} class for logins to
-  services like Google+ and Facebook.
+  <strong>Note:</strong> You can use the {@link android.webkit.WebView} class
+  for logins to services like Google+ and Facebook.
 </p>
\ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 581c15b..6574e4e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -67,6 +67,8 @@
 
 import com.google.android.collect.Lists;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -1397,4 +1399,22 @@
         }
         return null; // not found
     }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("KeyguardUpdateMonitor state:");
+        pw.println("  SIM States:");
+        for (SimData data : mSimDatas.values()) {
+            pw.println("    " + data.toString());
+        }
+        pw.println("  Subs:");
+        if (mSubscriptionInfo != null) {
+            for (int i = 0; i < mSubscriptionInfo.size(); i++) {
+                pw.println("    " + mSubscriptionInfo.get(i));
+            }
+        }
+        pw.println("  Service states:");
+        for (int subId : mServiceStates.keySet()) {
+            pw.println("    " + subId + "=" + mServiceStates.get(subId));
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 048fb9a..348d0ec 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -625,9 +625,13 @@
                 mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
     }
 
+    public boolean isPasspoint() {
+        return mConfig != null && mConfig.isPasspoint();
+    }
+
     /** Return whether the given {@link WifiInfo} is for this access point. */
     private boolean isInfoForThisAccessPoint(WifiInfo info) {
-        if (networkId != WifiConfiguration.INVALID_NETWORK_ID) {
+        if (isPasspoint() == false && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
             return networkId == info.getNetworkId();
         } else {
             // Might be an ephemeral connection with no WifiConfiguration. Try matching on SSID.
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b41e1ac..6e5dc3f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -51,7 +51,6 @@
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
diff --git a/packages/SystemUI/src/com/android/systemui/SysUIToast.java b/packages/SystemUI/src/com/android/systemui/SysUIToast.java
new file mode 100644
index 0000000..89bc82f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SysUIToast.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui;
+
+import android.content.Context;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+public class SysUIToast {
+
+    public static Toast makeText(Context context, CharSequence text, int duration) {
+        Toast toast = Toast.makeText(context, text, duration);
+        toast.getWindowParams().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        return toast;
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 359ed5f..781ab1c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -33,6 +33,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
+import com.android.systemui.SysUIToast;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.volume.ZenModePanel;
@@ -102,7 +103,7 @@
         if (mController.isVolumeRestricted()) {
             // Collapse the panels, so the user can see the toast.
             mHost.collapsePanels();
-            Toast.makeText(mContext, mContext.getString(
+            SysUIToast.makeText(mContext, mContext.getString(
                     com.android.internal.R.string.error_message_change_not_allowed),
                     Toast.LENGTH_LONG).show();
             return;
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 891cc73..f0e50f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -98,6 +98,7 @@
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.DemoMode;
@@ -2704,6 +2705,9 @@
         } else {
             pw.println("  mHeadsUpManager: null");
         }
+        if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
+            KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
+        }
 
         pw.println("SharedPreferences:");
         for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 24e3c78..81f2d532 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -661,8 +661,8 @@
                     for (int i = start /* get out of normal index range */; i < start + num; i++) {
                         subs.add(addSignalController(i, i));
                     }
+                    mCallbackHandler.setSubs(subs);
                 }
-                mCallbackHandler.setSubs(subs);
             }
             String nosim = args.getString("nosim");
             if (nosim != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index ca6aaeb..3f5ca58 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -103,6 +103,11 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mEnabledSwitch) {
+            if (newValue != Boolean.TRUE) {
+                // Make sure we aren't in demo mode when disabling it.
+                mOnSwitch.setChecked(false);
+                stopDemoMode();
+            }
             setGlobal(DEMO_MODE_ALLOWED, newValue == Boolean.TRUE ? 1 : 0);
         } else if (preference == mOnSwitch) {
             if (newValue == Boolean.TRUE) {
@@ -123,7 +128,7 @@
         getContext().sendBroadcast(intent);
 
         intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK);
-        intent.putExtra("hhmm", "0520");
+        intent.putExtra("hhmm", "0600");
         getContext().sendBroadcast(intent);
 
         intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index f0fc399..417f18d 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -48,6 +48,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.storage.MountServiceInternal;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -60,6 +61,7 @@
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IAppOpsCallback;
+import com.android.internal.os.Zygote;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
@@ -245,6 +247,34 @@
                 scheduleFastWriteLocked();
             }
         }
+
+        MountServiceInternal mountServiceInternal = LocalServices.getService(
+                MountServiceInternal.class);
+        mountServiceInternal.addExternalStoragePolicy(
+                new MountServiceInternal.ExternalStorageMountPolicy() {
+                    @Override
+                    public int getMountMode(int uid, String packageName) {
+                        if (Process.isIsolated(uid)) {
+                            return Zygote.MOUNT_EXTERNAL_NONE;
+                        }
+                        if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid,
+                                packageName) != AppOpsManager.MODE_ALLOWED) {
+                            return Zygote.MOUNT_EXTERNAL_NONE;
+                        }
+                        if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid,
+                                packageName) != AppOpsManager.MODE_ALLOWED) {
+                            return Zygote.MOUNT_EXTERNAL_READ;
+                        }
+                        return Zygote.MOUNT_EXTERNAL_WRITE;
+                    }
+
+                    @Override
+                    public boolean hasExternalStorage(int uid, String packageName) {
+                        final int mountMode = getMountMode(uid, packageName);
+                        return mountMode == Zygote.MOUNT_EXTERNAL_READ
+                                || mountMode == Zygote.MOUNT_EXTERNAL_WRITE;
+                    }
+                });
     }
 
     public void packageRemoved(int uid, String packageName) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 39c2891..eb74ab0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -407,6 +407,10 @@
     // sequence number of NetworkRequests
     private int mNextNetworkRequestId = 1;
 
+    // NetworkRequest activity String log entries.
+    private static final int MAX_NETWORK_REQUEST_LOGS = 20;
+    private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
+
     // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results
     private static final int MAX_VALIDATION_LOGS = 10;
     private final ArrayDeque<Pair<Network,ReadOnlyLocalLog>> mValidationLogs =
@@ -559,8 +563,9 @@
             final DetailedState state = nai.networkInfo.getDetailedState();
             for (int type = 0; type < mTypeLists.length; type++) {
                 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+                final boolean contains = (list != null && list.contains(nai));
                 final boolean isFirst = (list != null && list.size() > 0 && nai == list.get(0));
-                if (isFirst || isDefault) {
+                if (isFirst || (contains && isDefault)) {
                     maybeLogBroadcast(nai, state, type, isDefault);
                     sendLegacyNetworkBroadcast(nai, state, type);
                 }
@@ -609,8 +614,10 @@
         if (DBG) log("ConnectivityService starting up");
 
         mDefaultRequest = createInternetRequestForTransport(-1);
-        mNetworkRequests.put(mDefaultRequest, new NetworkRequestInfo(
-                null, mDefaultRequest, new Binder(), NetworkRequestInfo.REQUEST));
+        NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest,
+                new Binder(), NetworkRequestInfo.REQUEST);
+        mNetworkRequests.put(mDefaultRequest, defaultNRI);
+        mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
 
         mDefaultMobileDataRequest = createInternetRequestForTransport(
                 NetworkCapabilities.TRANSPORT_CELLULAR);
@@ -1858,6 +1865,12 @@
                     pw.decreaseIndent();
                 }
             }
+
+            pw.println();
+            pw.println("mNetworkRequestInfoLogs (most recent first):");
+            pw.increaseIndent();
+            mNetworkRequestInfoLogs.reverseDump(fd, pw, args);
+            pw.decreaseIndent();
         }
     }
 
@@ -2207,6 +2220,7 @@
 
     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
         mNetworkRequests.put(nri.request, nri);
+        mNetworkRequestInfoLogs.log("REGISTER " + nri);
         rematchAllNetworksAndRequests(null, 0);
         if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
             sendUpdatedScoreToFactories(nri.request, 0);
@@ -2256,6 +2270,7 @@
             if (DBG) log("releasing NetworkRequest " + request);
             nri.unlinkDeathRecipient();
             mNetworkRequests.remove(request);
+            mNetworkRequestInfoLogs.log("RELEASE " + nri);
             if (nri.isRequest) {
                 // Find all networks that are satisfying this request and remove the request
                 // from their request lists.
@@ -3528,8 +3543,9 @@
         }
 
         public String toString() {
-            return (isRequest ? "Request" : "Listen") + " from uid/pid:" + mUid + "/" +
-                    mPid + " for " + request +
+            return (isRequest ? "Request" : "Listen") +
+                    " from uid/pid:" + mUid + "/" + mPid +
+                    " for " + request +
                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
         }
     }
@@ -3559,9 +3575,9 @@
 
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
                 nextNetworkRequestId());
-        if (DBG) log("requestNetwork for " + networkRequest);
         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
                 NetworkRequestInfo.REQUEST);
+        if (DBG) log("requestNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
         if (timeoutMs > 0) {
@@ -3624,9 +3640,9 @@
 
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
                 nextNetworkRequestId());
-        if (DBG) log("pendingRequest for " + networkRequest + " to trigger " + operation);
         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
                 NetworkRequestInfo.REQUEST);
+        if (DBG) log("pendingRequest for " + nri);
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
                 nri));
         return networkRequest;
@@ -3674,11 +3690,11 @@
             enforceAccessPermission();
         }
 
-        NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
-                networkCapabilities), TYPE_NONE, nextNetworkRequestId());
-        if (DBG) log("listenForNetwork for " + networkRequest);
+        NetworkRequest networkRequest = new NetworkRequest(
+                new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
                 NetworkRequestInfo.LISTEN);
+        if (DBG) log("listenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
         return networkRequest;
@@ -3692,11 +3708,11 @@
             enforceAccessPermission();
         }
 
-        NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
-                networkCapabilities), TYPE_NONE, nextNetworkRequestId());
-        if (DBG) log("pendingListenForNetwork for " + networkRequest + " to trigger " + operation);
+        NetworkRequest networkRequest = new NetworkRequest(
+                new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
                 NetworkRequestInfo.LISTEN);
+        if (DBG) log("pendingListenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
     }
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index da552dd..bc61c3d3 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -68,6 +68,8 @@
 import android.os.storage.IMountServiceListener;
 import android.os.storage.IMountShutdownObserver;
 import android.os.storage.IObbActionListener;
+import android.os.storage.MountServiceInternal;
+import android.os.storage.MountServiceInternal.ExternalStorageMountPolicy;
 import android.os.storage.OnObbStateChangeListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
@@ -127,6 +129,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -307,16 +310,6 @@
     @GuardedBy("mLock")
     private String mMoveTargetUuid;
 
-    private DiskInfo findDiskById(String id) {
-        synchronized (mLock) {
-            final DiskInfo disk = mDisks.get(id);
-            if (disk != null) {
-                return disk;
-            }
-        }
-        throw new IllegalArgumentException("No disk found for ID " + id);
-    }
-
     private VolumeInfo findVolumeByIdOrThrow(String id) {
         synchronized (mLock) {
             final VolumeInfo vol = mVolumes.get(id);
@@ -456,6 +449,9 @@
     /** Map from raw paths to {@link ObbState}. */
     final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>();
 
+    // Not guarded by a lock.
+    private final MountServiceInternalImpl mMountServiceInternal = new MountServiceInternalImpl();
+
     class ObbState implements IBinder.DeathRecipient {
         public ObbState(String rawPath, String canonicalPath, int callingUid,
                 IObbActionListener token, int nonce) {
@@ -807,7 +803,7 @@
             for (int i = 0; i < mVolumes.size(); i++) {
                 final VolumeInfo vol = mVolumes.valueAt(i);
                 if (vol.isVisibleToUser(userId) && vol.isMountedReadable()) {
-                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId);
+                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
                     mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
 
                     final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
@@ -1250,7 +1246,7 @@
             // user-specific broadcasts.
             for (int userId : mStartedUsers) {
                 if (vol.isVisibleToUser(userId)) {
-                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId);
+                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
                     mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
 
                     mCallbacks.notifyStorageStateChanged(userVol.getPath(), oldStateEnv,
@@ -1370,6 +1366,8 @@
             readSettingsLocked();
         }
 
+        LocalServices.addService(MountServiceInternal.class, mMountServiceInternal);
+
         /*
          * Create the connection to vold with a maximum queue of twice the
          * amount of containers we'd ever expect to have. This keeps an
@@ -1787,27 +1785,28 @@
         }
     }
 
-    @Override
-    public void remountUid(int uid) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+    private void remountUidExternalStorage(int uid, int mode) {
         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";
+        String modeName = "none";
+        switch (mode) {
+            case Zygote.MOUNT_EXTERNAL_DEFAULT: {
+                modeName = "default";
+            } break;
+
+            case Zygote.MOUNT_EXTERNAL_READ: {
+                modeName = "read";
+            } break;
+
+            case Zygote.MOUNT_EXTERNAL_WRITE: {
+                modeName = "write";
+            } break;
         }
 
         try {
-            mConnector.execute("volume", "remount_uid", uid, mode);
+            mConnector.execute("volume", "remount_uid", uid, modeName);
         } catch (NativeDaemonConnectorException e) {
-            Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e);
+            Slog.w(TAG, "Failed to remount UID " + uid + " as " + modeName + ": " + e);
         }
     }
 
@@ -2598,15 +2597,20 @@
     }
 
     @Override
-    public StorageVolume[] getVolumeList(int userId) {
+    public StorageVolume[] getVolumeList(int uid, String packageName) {
         final ArrayList<StorageVolume> res = new ArrayList<>();
         boolean foundPrimary = false;
 
+        final int userId = UserHandle.getUserId(uid);
+        final boolean reportUnmounted = !mMountServiceInternal.hasExternalStorage(
+                uid, packageName);
+
         synchronized (mLock) {
             for (int i = 0; i < mVolumes.size(); i++) {
                 final VolumeInfo vol = mVolumes.valueAt(i);
                 if (vol.isVisibleToUser(userId)) {
-                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId);
+                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
+                            reportUnmounted);
                     if (vol.isPrimary()) {
                         res.add(0, userVol);
                         foundPrimary = true;
@@ -3379,4 +3383,50 @@
             mCryptConnector.monitor();
         }
     }
+
+    private final class MountServiceInternalImpl extends MountServiceInternal {
+        // Not guarded by a lock.
+        private final CopyOnWriteArrayList<ExternalStorageMountPolicy> mPolicies =
+                new CopyOnWriteArrayList<>();
+
+        @Override
+        public void addExternalStoragePolicy(ExternalStorageMountPolicy policy) {
+            // No locking - CopyOnWriteArrayList
+            mPolicies.add(policy);
+        }
+
+        @Override
+        public void onExternalStoragePolicyChanged(int uid, String packageName) {
+            final int mountMode = getExternalStorageMountMode(uid, packageName);
+            remountUidExternalStorage(uid, mountMode);
+        }
+
+        @Override
+        public int getExternalStorageMountMode(int uid, String packageName) {
+            // No locking - CopyOnWriteArrayList
+            int mountMode = Integer.MAX_VALUE;
+            for (ExternalStorageMountPolicy policy : mPolicies) {
+                final int policyMode = policy.getMountMode(uid, packageName);
+                if (policyMode == Zygote.MOUNT_EXTERNAL_NONE) {
+                    return Zygote.MOUNT_EXTERNAL_NONE;
+                }
+                mountMode = Math.min(mountMode, policyMode);
+            }
+            if (mountMode == Integer.MAX_VALUE) {
+                return Zygote.MOUNT_EXTERNAL_NONE;
+            }
+            return mountMode;
+        }
+
+        public boolean hasExternalStorage(int uid, String packageName) {
+            // No locking - CopyOnWriteArrayList
+            for (ExternalStorageMountPolicy policy : mPolicies) {
+                final boolean policyHasStorage = policy.hasExternalStorage(uid, packageName);
+                if (!policyHasStorage) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 36d64aa..a06bb30 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
@@ -360,12 +361,20 @@
                 + " callback.asBinder=" + callback.asBinder());
         }
 
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.READ_PHONE_STATE, null);
+        try {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+                    "addOnSubscriptionsChangedListener");
+            // SKIP checking for run-time permission since obtained PRIVILEGED
+        } catch (SecurityException e) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PHONE_STATE,
+                    "addOnSubscriptionsChangedListener");
 
-        if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            return;
+            if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
+                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                return;
+            }
         }
 
         Record r;
@@ -471,9 +480,15 @@
             checkListenerPermission(events);
 
             if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-                if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
-                    return;
+                try {
+                    mContext.enforceCallingPermission(
+                            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
+                    // SKIP checking for run-time permission since obtained PRIVILEGED
+                } catch (SecurityException e) {
+                    if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
+                            callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                        return;
+                    }
                 }
             }
 
@@ -646,6 +661,12 @@
     }
 
     private boolean canReadPhoneState(String callingPackage) {
+        if (mContext.checkCallingPermission(
+                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) ==
+                PackageManager.PERMISSION_GRANTED) {
+            // SKIP checking for run-time permission since obtained PRIVILEGED
+            return true;
+        }
         boolean canReadPhoneState = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
         if (canReadPhoneState &&
@@ -1432,6 +1453,10 @@
             intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
         }
 
+        // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those
+        // that have the runtime one
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 android.Manifest.permission.READ_PHONE_STATE,
                 AppOpsManager.OP_READ_PHONE_STATE);
@@ -1563,8 +1588,14 @@
         }
 
         if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PHONE_STATE, null);
+            try {
+                mContext.enforceCallingPermission(
+                        android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
+                // SKIP checking for run-time permission since obtained PRIVILEGED
+            } catch (SecurityException e) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.READ_PHONE_STATE, null);
+            }
         }
 
         if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6e94647..5bfca10 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,7 +18,10 @@
 
 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.Manifest.permission.WRITE_MEDIA_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;
@@ -62,6 +65,7 @@
 import android.os.TransactionTooLargeException;
 import android.os.WorkSource;
 import android.os.storage.IMountService;
+import android.os.storage.MountServiceInternal;
 import android.os.storage.StorageManager;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.ArrayMap;
@@ -3219,7 +3223,10 @@
                     checkTime(startTime, "startProcess: getting gids from package manager");
                     final IPackageManager pm = AppGlobals.getPackageManager();
                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
-                    mountExternal = pm.getMountExternalMode(uid);
+                    MountServiceInternal mountServiceInternal = LocalServices.getService(
+                            MountServiceInternal.class);
+                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
+                            app.info.packageName);
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
                 }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 8c3a950..470bbb0e 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2669,8 +2669,13 @@
             if (!r.finishing) {
                 if (!mService.isSleeping()) {
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
-                    requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
-                            "stop-no-history", false);
+                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
+                            "stop-no-history", false)) {
+                        // Activity was finished, no need to continue trying to schedule stop.
+                        adjustFocusedActivityLocked(r, "stopActivityFinished");
+                        r.resumeKeyDispatchingLocked();
+                        return;
+                    }
                 } else {
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
                             + " on stop because we're just sleeping");
@@ -2963,6 +2968,7 @@
         r.state = ActivityState.FINISHING;
 
         if (mode == FINISH_IMMEDIATELY
+                || (mode == FINISH_AFTER_PAUSE && prevState == ActivityState.PAUSED)
                 || prevState == ActivityState.STOPPED
                 || prevState == ActivityState.INITIALIZING) {
             // If this activity is already stopped, we can just finish
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 7a74729..e3c6037 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -29,6 +29,7 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Debug;
 import android.os.UserHandle;
 import android.provider.CalendarContract;
 import android.provider.ContactsContract;
@@ -174,7 +175,7 @@
 
         synchronized (mService.mPackages) {
             for (PackageParser.Package pkg : mService.mPackages.values()) {
-                if (!isSysComponentOrPersistentPrivApp(pkg)
+                if (!isSysComponentOrPersistentPlatformSignedPrivApp(pkg)
                         || !doesPackageSupportRuntimePermissions(pkg)) {
                     continue;
                 }
@@ -344,7 +345,6 @@
             Intent cbrIntent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
             PackageParser.Package cbrPackage =
                     getDefaultSystemHandlerActivityPackageLPr(cbrIntent, userId);
-
             if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) {
                 grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, false, userId);
             }
@@ -625,8 +625,9 @@
 
     private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
             Intent intent, int userId) {
-        List<ResolveInfo> handlers = mService.queryIntentActivities(intent,
-                intent.resolveType(mService.mContext.getContentResolver()), 0, userId);
+        List<ResolveInfo> handlers = mService.mActivities.queryIntent(intent,
+                intent.resolveType(mService.mContext.getContentResolver()),
+                PackageManager.GET_DISABLED_COMPONENTS, userId);
         final int handlerCount = handlers.size();
         for (int i = 0; i < handlerCount; i++) {
             ResolveInfo handler = handlers.get(i);
@@ -650,8 +651,9 @@
         for (String syncAdapterPackageName : syncAdapterPackageNames) {
             homeIntent.setPackage(syncAdapterPackageName);
 
-            List<ResolveInfo> homeActivities = mService.queryIntentActivities(homeIntent,
-                    homeIntent.resolveType(mService.mContext.getContentResolver()), 0, userId);
+            List<ResolveInfo> homeActivities = mService.mActivities.queryIntent(homeIntent,
+                    homeIntent.resolveType(mService.mContext.getContentResolver()),
+                    PackageManager.GET_DISABLED_COMPONENTS, userId);
             if (!homeActivities.isEmpty()) {
                 continue;
             }
@@ -681,7 +683,7 @@
     private PackageParser.Package getSystemPackageLPr(String packageName) {
         PackageParser.Package pkg = getPackageLPr(packageName);
         if (pkg != null && pkg.isSystemApp()) {
-            return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
+            return !isSysComponentOrPersistentPlatformSignedPrivApp(pkg) ? pkg : null;
         }
         return null;
     }
@@ -730,11 +732,16 @@
         }
     }
 
-    private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
-        return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
-                || ((pkg.applicationInfo.privateFlags
-                & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
-                && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
+    private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageParser.Package pkg) {
+        if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
+            return true;
+        }
+        if ((pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) == 0
+                || (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
+            return false;
+        }
+        return PackageManagerService.compareSignatures(mService.mPlatformPackage.mSignatures,
+                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
     }
 
     private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index bfb803d..ef9bc8b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -62,6 +62,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_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.PackageParser.isApkFile;
 import static android.os.Process.PACKAGE_INFO_GID;
@@ -143,10 +144,10 @@
 import android.content.res.Resources;
 import android.hardware.display.DisplayManager;
 import android.net.Uri;
+import android.os.Debug;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Environment;
 import android.os.Environment.UserEnvironment;
 import android.os.FileUtils;
@@ -166,6 +167,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.IMountService;
+import android.os.storage.MountServiceInternal;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
@@ -284,7 +286,7 @@
     static final boolean DEBUG_PREFERRED = false;
     static final boolean DEBUG_UPGRADE = false;
     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
-    private static final boolean DEBUG_BACKUP = true;
+    private static final boolean DEBUG_BACKUP = false;
     private static final boolean DEBUG_INSTALL = false;
     private static final boolean DEBUG_REMOVE = false;
     private static final boolean DEBUG_BROADCASTS = false;
@@ -2727,23 +2729,6 @@
         return null;
     }
 
-    @Override
-    public int getMountExternalMode(int uid) {
-        if (Process.isIsolated(uid)) {
-            return Zygote.MOUNT_EXTERNAL_NONE;
-        } else {
-            if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
-                return Zygote.MOUNT_EXTERNAL_DEFAULT;
-            } 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) {
@@ -3461,13 +3446,15 @@
         // Only need to do this if user is initialized. Otherwise it's a new user
         // and there are no processes running as the user yet and there's no need
         // to make an expensive call to remount processes for the changed permissions.
-        if ((READ_EXTERNAL_STORAGE.equals(name)
-                || WRITE_EXTERNAL_STORAGE.equals(name))
-                && sUserManager.isInitialized(userId)) {
+        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);
+                if (sUserManager.isInitialized(userId)) {
+                    MountServiceInternal mountServiceInternal = LocalServices.getService(
+                            MountServiceInternal.class);
+                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
+                }
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -4431,8 +4418,11 @@
             // cross-profile app linking works only towards the parent.
             final UserInfo parent = getProfileParent(sourceUserId);
             synchronized(mPackages) {
-                return getCrossProfileDomainPreferredLpr(intent, resolvedType, 0, sourceUserId,
-                        parent.id) != null;
+                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
+                        intent, resolvedType, 0, sourceUserId, parent.id);
+                return xpDomainInfo != null
+                        && xpDomainInfo.bestDomainVerificationStatus !=
+                                INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
             }
         }
         return false;
@@ -4527,8 +4517,8 @@
                     } else if (result.size() <= 1) {
                         return result;
                     }
-                    result = filterCandidatesWithDomainPreferredActivitiesLPr(flags, result,
-                            xpDomainInfo);
+                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
+                            xpDomainInfo, userId);
                     Collections.sort(result, mResolvePrioritySorter);
                 }
                 return result;
@@ -4577,7 +4567,8 @@
             if (ps == null) {
                 continue;
             }
-            int status = getDomainVerificationStatusLPr(ps, parentUserId);
+            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
+            int status = (int)(verificationState >> 32);
             if (result == null) {
                 result = new CrossProfileDomainInfo();
                 result.resolveInfo =
@@ -4644,14 +4635,16 @@
         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
     }
 
-    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(
-            int flags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo) {
+    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
+            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
+            int userId) {
+        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
+
         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
-            Slog.v("TAG", "Filtering results with preferred activities. Candidates count: " +
+            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
                     candidates.size());
         }
 
-        final int userId = UserHandle.getCallingUserId();
         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
@@ -4674,11 +4667,17 @@
                         continue;
                     }
                     // Try to get the status from User settings first
-                    int status = getDomainVerificationStatusLPr(ps, userId);
+                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+                    int status = (int)(packedStatus >> 32);
+                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
                         if (DEBUG_DOMAIN_VERIFICATION) {
-                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName);
+                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
+                                    + " : linkgen=" + linkGeneration);
                         }
+                        // Use link-enabled generation as preferredOrder, i.e.
+                        // prefer newly-enabled over earlier-enabled.
+                        info.preferredOrder = linkGeneration;
                         alwaysList.add(info);
                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
                         if (DEBUG_DOMAIN_VERIFICATION) {
@@ -4694,7 +4693,7 @@
                     }
                 }
             }
-            // First try to add the "always" resolution for the current user if there is any
+            // First try to add the "always" resolution(s) for the current user, if any
             if (alwaysList.size() > 0) {
                 result.addAll(alwaysList);
             // if there is an "always" for the parent user, add it.
@@ -4712,26 +4711,41 @@
                     result.add(xpDomainInfo.resolveInfo);
                 }
                 // Also add Browsers (all of them or only the default one)
-                if ((flags & MATCH_ALL) != 0) {
+                if ((matchFlags & MATCH_ALL) != 0) {
                     result.addAll(matchAllList);
                 } else {
-                    // Try to add the Default Browser if we can
+                    // Browser/generic handling case.  If there's a default browser, go straight
+                    // to that (but only if there is no other higher-priority match).
                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(
                             UserHandle.myUserId());
-                    if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
-                        boolean defaultBrowserFound = false;
-                        final int browserCount = matchAllList.size();
-                        for (int n=0; n<browserCount; n++) {
-                            ResolveInfo browser = matchAllList.get(n);
-                            if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) {
-                                result.add(browser);
-                                defaultBrowserFound = true;
-                                break;
+                    int maxMatchPrio = 0;
+                    ResolveInfo defaultBrowserMatch = null;
+                    final int numCandidates = matchAllList.size();
+                    for (int n = 0; n < numCandidates; n++) {
+                        ResolveInfo info = matchAllList.get(n);
+                        // track the highest overall match priority...
+                        if (info.priority > maxMatchPrio) {
+                            maxMatchPrio = info.priority;
+                        }
+                        // ...and the highest-priority default browser match
+                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
+                            if (defaultBrowserMatch == null
+                                    || (defaultBrowserMatch.priority < info.priority)) {
+                                if (debug) {
+                                    Slog.v(TAG, "Considering default browser match " + info);
+                                }
+                                defaultBrowserMatch = info;
                             }
                         }
-                        if (!defaultBrowserFound) {
-                            result.addAll(matchAllList);
+                    }
+                    if (defaultBrowserMatch != null
+                            && defaultBrowserMatch.priority >= maxMatchPrio
+                            && !TextUtils.isEmpty(defaultBrowserPackageName))
+                    {
+                        if (debug) {
+                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
                         }
+                        result.add(defaultBrowserMatch);
                     } else {
                         result.addAll(matchAllList);
                     }
@@ -4755,15 +4769,19 @@
         return result;
     }
 
-    private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
-        int status = ps.getDomainVerificationStatusForUser(userId);
+    // Returns a packed value as a long:
+    //
+    // high 'int'-sized word: link status: undefined/ask/never/always.
+    // low 'int'-sized word: relative priority among 'always' results.
+    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
+        long result = ps.getDomainVerificationStatusForUser(userId);
         // if none available, get the master status
-        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
             if (ps.getIntentFilterVerificationInfo() != null) {
-                status = ps.getIntentFilterVerificationInfo().getStatus();
+                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
             }
         }
-        return status;
+        return result;
     }
 
     private ResolveInfo querySkipCurrentProfileIntents(
@@ -12959,7 +12977,7 @@
                         false, //hidden
                         null, null, null,
                         false, // blockUninstall
-                        INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+                        INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
                 if (!isSystemApp(ps)) {
                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
                         // Other user still have this package installed, so all
@@ -14435,6 +14453,33 @@
 
         mInstallerService.systemReady();
         mPackageDexOptimizer.systemReady();
+
+        MountServiceInternal mountServiceInternal = LocalServices.getService(
+                MountServiceInternal.class);
+        mountServiceInternal.addExternalStoragePolicy(
+                new MountServiceInternal.ExternalStorageMountPolicy() {
+            @Override
+            public int getMountMode(int uid, String packageName) {
+                if (Process.isIsolated(uid)) {
+                    return Zygote.MOUNT_EXTERNAL_NONE;
+                }
+                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
+                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
+                }
+                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
+                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
+                }
+                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
+                    return Zygote.MOUNT_EXTERNAL_READ;
+                }
+                return Zygote.MOUNT_EXTERNAL_WRITE;
+            }
+
+            @Override
+            public boolean hasExternalStorage(int uid, String packageName) {
+                return true;
+            }
+        });
     }
 
     @Override
@@ -14882,8 +14927,8 @@
                             pw.println();
                             count = 0;
                             for (PackageSetting ps : allPackageSettings) {
-                                final int status = ps.getDomainVerificationStatusForUser(userId);
-                                if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+                                final long status = ps.getDomainVerificationStatusForUser(userId);
+                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
                                     continue;
                                 }
                                 pw.println(prefix + "Package: " + ps.name);
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 6f46f69..4faf75a 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -341,7 +341,8 @@
     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
             boolean notLaunched, boolean hidden,
             String lastDisableAppCaller, ArraySet<String> enabledComponents,
-            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState) {
+            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
+            int linkGeneration) {
         PackageUserState state = modifyUserState(userId);
         state.enabled = enabled;
         state.installed = installed;
@@ -353,6 +354,7 @@
         state.disabledComponents = disabledComponents;
         state.blockUninstall = blockUninstall;
         state.domainVerificationStatus = domainVerifState;
+        state.appLinkGeneration = linkGeneration;
     }
 
     ArraySet<String> getEnabledComponents(int userId) {
@@ -449,12 +451,23 @@
         verificationInfo = info;
     }
 
-    int getDomainVerificationStatusForUser(int userId) {
-        return readUserState(userId).domainVerificationStatus;
+    // Returns a packed value as a long:
+    //
+    // high 'int'-sized word: link status: undefined/ask/never/always.
+    // low 'int'-sized word: relative priority among 'always' results.
+    long getDomainVerificationStatusForUser(int userId) {
+        PackageUserState state = readUserState(userId);
+        long result = (long) state.appLinkGeneration;
+        result |= ((long) state.domainVerificationStatus) << 32;
+        return result;
     }
 
-    void setDomainVerificationStatusForUser(int status, int userId) {
-        modifyUserState(userId).domainVerificationStatus = status;
+    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
+        PackageUserState state = modifyUserState(userId);
+        state.domainVerificationStatus = status;
+        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+            state.appLinkGeneration = generation;
+        }
     }
 
     void clearDomainVerificationStatusForUser(int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index bdcd714..312b7b3 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -87,6 +87,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.util.Xml;
 
 import java.io.BufferedOutputStream;
@@ -196,6 +197,7 @@
     private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
     private static final String ATTR_PACKAGE_NAME= "packageName";
     private static final String ATTR_FINGERPRINT = "fingerprint";
+    private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
 
     private final Object mLock;
 
@@ -294,6 +296,9 @@
     // For every user, it is used to find the package name of the default Browser App.
     final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>();
 
+    // App-link priority tracking, per-user
+    final SparseIntArray mNextAppLinkGeneration = new SparseIntArray();
+
     final StringBuilder mReadMessages = new StringBuilder();
 
     /**
@@ -624,7 +629,7 @@
                                     false, // hidden
                                     null, null, null,
                                     false, // blockUninstall
-                                    INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+                                    INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
                             writePackageRestrictionsLPr(user.id);
                         }
                     }
@@ -1051,7 +1056,7 @@
             }
             return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
         }
-        int status = ps.getDomainVerificationStatusForUser(userId);
+        int status = (int)(ps.getDomainVerificationStatusForUser(userId) >> 32);
         if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
             if (ps.getIntentFilterVerificationInfo() != null) {
                 status = ps.getIntentFilterVerificationInfo().getStatus();
@@ -1060,7 +1065,7 @@
         return status;
     }
 
-    boolean updateIntentFilterVerificationStatusLPw(String packageName, int status, int userId) {
+    boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId) {
         // Update the status for the current package
         PackageSetting current = mPackages.get(packageName);
         if (current == null) {
@@ -1070,7 +1075,15 @@
             return false;
         }
 
-        current.setDomainVerificationStatusForUser(status, userId);
+        final int alwaysGeneration;
+        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+            alwaysGeneration = mNextAppLinkGeneration.get(userId) + 1;
+            mNextAppLinkGeneration.put(userId, alwaysGeneration);
+        } else {
+            alwaysGeneration = 0;
+        }
+
+        current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId);
         return true;
     }
 
@@ -1382,7 +1395,7 @@
                                 false,  // hidden
                                 null, null, null,
                                 false, // blockUninstall
-                                INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+                                INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
                     }
                     return;
                 }
@@ -1404,6 +1417,8 @@
                 return;
             }
 
+            int maxAppLinkGeneration = 0;
+
             int outerDepth = parser.getDepth();
             PackageSetting ps = null;
             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1457,6 +1472,12 @@
                             PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED :
                             Integer.parseInt(verifStateStr);
 
+                    final String linkGenStr = parser.getAttributeValue(null, ATTR_APP_LINK_GENERATION);
+                    final int linkGeneration = linkGenStr == null ? 0 : Integer.parseInt(linkGenStr);
+                    if (linkGeneration > maxAppLinkGeneration) {
+                        maxAppLinkGeneration = linkGeneration;
+                    }
+
                     ArraySet<String> enabledComponents = null;
                     ArraySet<String> disabledComponents = null;
 
@@ -1478,7 +1499,7 @@
 
                     ps.setUserState(userId, enabled, installed, stopped, notLaunched, hidden,
                             enabledCaller, enabledComponents, disabledComponents, blockUninstall,
-                            verifState);
+                            verifState, linkGeneration);
                 } else if (tagName.equals("preferred-activities")) {
                     readPreferredActivitiesLPw(parser, userId);
                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
@@ -1496,6 +1517,8 @@
 
             str.close();
 
+            mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
+
         } catch (XmlPullParserException e) {
             mReadMessages.append("Error reading: " + e.toString());
             PackageManagerService.reportSettingsProblem(Log.ERROR,
@@ -1749,6 +1772,10 @@
                         serializer.attribute(null, ATTR_DOMAIN_VERIFICATON_STATE,
                                 Integer.toString(ustate.domainVerificationStatus));
                     }
+                    if (ustate.appLinkGeneration != 0) {
+                        serializer.attribute(null, ATTR_APP_LINK_GENERATION,
+                                Integer.toString(ustate.appLinkGeneration));
+                    }
                     if (ustate.enabledComponents != null
                             && ustate.enabledComponents.size() > 0) {
                         serializer.startTag(null, TAG_ENABLED_COMPONENTS);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 87efb8d..9e41f70 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -44,6 +44,9 @@
 import android.database.ContentObserver;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiPlaybackClient;
+import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioSystem;
@@ -356,6 +359,7 @@
     boolean mSystemReady;
     boolean mSystemBooted;
     boolean mHdmiPlugged;
+    HdmiControl mHdmiControl;
     IUiModeManager mUiModeManager;
     int mUiMode;
     int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -1212,6 +1216,9 @@
     }
 
     private void handleShortPressOnHome() {
+        // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
+        getHdmiControl().turnOnTv();
+
         // If there's a dream running then use home to escape the dream
         // but don't actually go home.
         if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
@@ -1223,6 +1230,46 @@
         launchHomeFromHotKey();
     }
 
+    /**
+     * Creates an accessor to HDMI control service that performs the operation of
+     * turning on TV (optional) and switching input to us. If HDMI control service
+     * is not available or we're not a HDMI playback device, the operation is no-op.
+     */
+    private HdmiControl getHdmiControl() {
+        if (null == mHdmiControl) {
+            HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService(
+                        Context.HDMI_CONTROL_SERVICE);
+            HdmiPlaybackClient client = null;
+            if (manager != null) {
+                client = manager.getPlaybackClient();
+            }
+            mHdmiControl = new HdmiControl(client);
+        }
+        return mHdmiControl;
+    }
+
+    private static class HdmiControl {
+        private final HdmiPlaybackClient mClient;
+
+        private HdmiControl(HdmiPlaybackClient client) {
+            mClient = client;
+        }
+
+        public void turnOnTv() {
+            if (mClient == null) {
+                return;
+            }
+            mClient.oneTouchPlay(new OneTouchPlayCallback() {
+                @Override
+                public void onComplete(int result) {
+                    if (result != HdmiControlManager.RESULT_SUCCESS) {
+                        Log.w(TAG, "One touch play failed: " + result);
+                    }
+                }
+            });
+        }
+    }
+
     private void handleLongPressOnHome(int deviceId) {
         if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
             mHomeConsumed = true;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 89e9d2e..0bb04f8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4230,7 +4230,7 @@
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#canChangeDtmfToneLength", e);
         } catch (SecurityException e) {
-            Log.w(TAG, "Permission error calling ITelephony#canChangeDtmfToneLength", e);
+            Log.e(TAG, "Permission error calling ITelephony#canChangeDtmfToneLength", e);
         }
         return false;
     }
@@ -4248,6 +4248,8 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isWorldPhone", e);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Permission error calling ITelephony#isWorldPhone", e);
         }
         return false;
     }
@@ -4265,6 +4267,8 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isTtyModeSupported", e);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Permission error calling ITelephony#isTtyModeSupported", e);
         }
         return false;
     }
@@ -4283,6 +4287,8 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isHearingAidCompatibilitySupported", e);
+        } catch (SecurityException e) {
+            Log.e(TAG, "Permission error calling ITelephony#isHearingAidCompatibilitySupported", e);
         }
         return false;
     }