Merge "Fix Floating toolbar overflow width." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 2802062..376c2c3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3879,6 +3879,7 @@
     field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
     field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
     field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+    field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
     field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
     field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
     field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -3891,6 +3892,7 @@
     field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
     field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
     field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+    field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
   }
 
   public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5615,8 +5617,8 @@
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
-    method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
-    method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+    method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
     method public void enableSystemApp(android.content.ComponentName, java.lang.String);
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -26424,6 +26426,7 @@
     field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+    field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 5713af2..57f3a30 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3989,6 +3989,7 @@
     field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
     field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
     field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+    field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
     field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
     field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
     field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4001,6 +4002,7 @@
     field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
     field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
     field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+    field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
   }
 
   public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5736,8 +5738,8 @@
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearProfileOwner(android.content.ComponentName);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
-    method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
-    method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+    method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
     method public void enableSystemApp(android.content.ComponentName, java.lang.String);
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -28485,6 +28487,7 @@
     field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+    field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8a61ec6..9faadd3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -229,8 +229,12 @@
     public static final int OP_READ_CELL_BROADCASTS = 57;
     /** @hide Inject mock location into the system. */
     public static final int OP_MOCK_LOCATION = 58;
+    /** @hide Read external storage. */
+    public static final int OP_READ_EXTERNAL_STORAGE = 59;
+    /** @hide Write external storage. */
+    public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
     /** @hide */
-    public static final int _NUM_OP = 59;
+    public static final int _NUM_OP = 61;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -313,6 +317,12 @@
     /** Inject mock location into the system. */
     public static final String OPSTR_MOCK_LOCATION
             = "android:mock_location";
+    /** Read external storage. */
+    public static final String OPSTR_READ_EXTERNAL_STORAGE
+            = "android:read_external_storage";
+    /** Write external storage. */
+    public static final String OPSTR_WRITE_EXTERNAL_STORAGE
+            = "android:write_external_storage";
 
     /**
      * This maps each operation to the operation that serves as the
@@ -381,7 +391,9 @@
             OP_USE_FINGERPRINT,
             OP_BODY_SENSORS,
             OP_READ_CELL_BROADCASTS,
-            OP_MOCK_LOCATION
+            OP_MOCK_LOCATION,
+            OP_READ_EXTERNAL_STORAGE,
+            OP_WRITE_EXTERNAL_STORAGE
     };
 
     /**
@@ -447,7 +459,9 @@
             OPSTR_USE_FINGERPRINT,
             OPSTR_BODY_SENSORS,
             OPSTR_READ_CELL_BROADCASTS,
-            OPSTR_MOCK_LOCATION
+            OPSTR_MOCK_LOCATION,
+            OPSTR_READ_EXTERNAL_STORAGE,
+            OPSTR_WRITE_EXTERNAL_STORAGE
     };
 
     /**
@@ -513,7 +527,9 @@
             "USE_FINGERPRINT",
             "BODY_SENSORS",
             "READ_CELL_BROADCASTS",
-            "MOCK_LOCATION"
+            "MOCK_LOCATION",
+            "OPSTR_READ_EXTERNAL_STORAGE",
+            "OPSTR_WRITE_EXTERNAL_STORAGE",
     };
 
     /**
@@ -579,7 +595,9 @@
             Manifest.permission.USE_FINGERPRINT,
             Manifest.permission.BODY_SENSORS,
             Manifest.permission.READ_CELL_BROADCASTS,
-            null
+            null,
+            Manifest.permission.READ_EXTERNAL_STORAGE,
+            Manifest.permission.WRITE_EXTERNAL_STORAGE,
     };
 
     /**
@@ -646,7 +664,9 @@
             null, // USE_FINGERPRINT
             null, // BODY_SENSORS
             null, // READ_CELL_BROADCASTS
-            null  // MOCK_LOCATION
+            null, // MOCK_LOCATION
+            null, // READ_EXTERNAL_STORAGE
+            null  // WRITE_EXTERNAL_STORAGE
     };
 
     /**
@@ -712,7 +732,9 @@
             false, // USE_FINGERPRINT
             false, // BODY_SENSORS
             false, // READ_CELL_BROADCASTS
-            false  // MOCK_LOCATION
+            false, // MOCK_LOCATION
+            false, // READ_EXTERNAL_STORAGE
+            false  // WRITE_EXTERNAL_STORAGE
     };
 
     /**
@@ -777,7 +799,9 @@
             AppOpsManager.MODE_ALLOWED,
             AppOpsManager.MODE_ALLOWED,
             AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ERRORED  // OP_MOCK_LOCATION
+            AppOpsManager.MODE_ERRORED,  // OP_MOCK_LOCATION
+            AppOpsManager.MODE_ALLOWED,
+            AppOpsManager.MODE_ALLOWED
     };
 
     /**
@@ -846,6 +870,8 @@
             false,
             false,
             false,
+            false,
+            false,
             false
     };
 
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 903411e..13030ca 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -717,6 +717,7 @@
                 break;
                 case OP_REPLACE: {
                     Fragment f = op.fragment;
+                    int containerId = f.mContainerId;
                     if (mManager.mAdded != null) {
                         for (int i = 0; i < mManager.mAdded.size(); i++) {
                             Fragment old = mManager.mAdded.get(i);
@@ -724,7 +725,7 @@
                                 Log.v(TAG,
                                         "OP_REPLACE: adding=" + f + " old=" + old);
                             }
-                            if (f == null || old.mContainerId == f.mContainerId) {
+                            if (old.mContainerId == containerId) {
                                 if (old == f) {
                                     op.fragment = f = null;
                                 } else {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d53157b..d28ff51 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3612,7 +3612,10 @@
      * @see UserHandle
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
+     *
+     * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
      */
+    @Deprecated
     public UserHandle createUser(@NonNull ComponentName admin, String name) {
         try {
             return mService.createUser(admin, name);
@@ -3646,7 +3649,10 @@
      * @see UserHandle
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
+     *
+     * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
      */
+    @Deprecated
     public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
             String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
         try {
@@ -3962,24 +3968,27 @@
      * <li>{@link Settings.Global#ADB_ENABLED}</li>
      * <li>{@link Settings.Global#AUTO_TIME}</li>
      * <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
-     * <li>{@link Settings.Global#BLUETOOTH_ON}
-     * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
-     * {@link android.bluetooth.BluetoothAdapter#enable()} and
-     * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
      * <li>{@link Settings.Global#DATA_ROAMING}</li>
-     * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
-     * <li>{@link Settings.Global#MODE_RINGER}</li>
-     * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
      * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
-     * <li>{@link Settings.Global#WIFI_ON}
-     * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
-     * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
      * <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
      * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
-     * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
-     * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
+     *   This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+     *   and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
      * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
      * </ul>
+     * <p>Changing the following settings has no effect as of
+     * {@link android.os.Build.VERSION_CODES#MNC}:
+     * <ul>
+     * <li>{@link Settings.Global#BLUETOOTH_ON}.
+     *   Use {@link android.bluetooth.BluetoothAdapter#enable()} and
+     *   {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
+     * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+     * <li>{@link Settings.Global#MODE_RINGER}.
+     *   Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
+     * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
+     * <li>{@link Settings.Global#WIFI_ON}.
+     *   Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
+     * </ul>
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param setting The name of the setting to update.
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 369b692..24647f38 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -372,13 +372,4 @@
             return new UsageEvents[size];
         }
     };
-
-    @Override
-    protected void finalize() throws Throwable {
-        super.finalize();
-        if (mParcel != null) {
-            mParcel.recycle();
-            mParcel = null;
-        }
-    }
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index d37dda0..6ede29b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1593,7 +1593,11 @@
             @NonNull ContentObserver observer) {
         Preconditions.checkNotNull(uri, "uri");
         Preconditions.checkNotNull(observer, "observer");
-        registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId());
+        registerContentObserver(
+                ContentProvider.getUriWithoutUserId(uri),
+                notifyForDescendents,
+                observer,
+                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
     }
 
     /** @hide - designated user version */
@@ -1659,7 +1663,11 @@
     public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
             boolean syncToNetwork) {
         Preconditions.checkNotNull(uri, "uri");
-        notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
+        notifyChange(
+                ContentProvider.getUriWithoutUserId(uri),
+                observer,
+                syncToNetwork,
+                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
     }
 
     /**
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 31aedad..cfd5bf1 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -517,7 +517,7 @@
      * Note that Http Proxies are only a hint - the system recommends their use, but it does
      * not enforce it and applications may ignore them.
      *
-     * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+     * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
      * @hide
      */
     public void setHttpProxy(ProxyInfo proxy) {
@@ -774,6 +774,43 @@
     }
 
     /**
+     * Evaluate whether the {@link InetAddress} is considered reachable.
+     *
+     * @return {@code true} if the given {@link InetAddress} is considered reachable,
+     *         {@code false} otherwise.
+     * @hide
+     */
+    public boolean isReachable(InetAddress ip) {
+        final List<RouteInfo> allRoutes = getAllRoutes();
+        // If we don't have a route to this IP address, it's not reachable.
+        final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
+        if (bestRoute == null) {
+            return false;
+        }
+
+        // TODO: better source address evaluation for destination addresses.
+
+        if (ip instanceof Inet4Address) {
+            // For IPv4, it suffices for now to simply have any address.
+            return hasIPv4Address();
+        } else if (ip instanceof Inet6Address) {
+            if (ip.isLinkLocalAddress()) {
+                // For now, just make sure link-local destinations have
+                // scopedIds set, since transmits will generally fail otherwise.
+                // TODO: verify it matches the ifindex of one of the interfaces.
+                return (((Inet6Address)ip).getScopeId() != 0);
+            }  else {
+                // For non-link-local destinations check that either the best route
+                // is directly connected or that some global preferred address exists.
+                // TODO: reconsider all cases (disconnected ULA networks, ...).
+                return (!bestRoute.hasGateway() || hasGlobalIPv6Address());
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * Compares this {@code LinkProperties} interface name against the target
      *
      * @param target LinkProperties to compare.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cc56969..e5afdde 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -562,6 +562,21 @@
             "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
 
     /**
+     * Activity Action: Show settings to toggle permission to draw on top of
+     * other apps.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MANAGE_OVERLAY_PERMISSION =
+            "android.settings.MANAGE_OVERLAY_PERMISSION";
+
+    /**
      * Activity Action: Show screen of details about a particular application.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index b78eca7..6dc66ea 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -40,6 +40,7 @@
     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;
     // Temporary constants go here, to await migration to MetricsConstants.
 
     public static void visible(Context context, int category) throws IllegalArgumentException {
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index c869722..b2699f8 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -167,6 +167,7 @@
                 // Content rect is moving.
                 mOriginatingView.removeCallbacks(mMovingOff);
                 mFloatingToolbarVisibilityHelper.setMoving(true);
+                mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
                 mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
 
                 mFloatingToolbar.setContentRect(mContentRectOnWindow);
@@ -174,9 +175,9 @@
             }
         } else {
             mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
             mContentRectOnWindow.setEmpty();
         }
-        mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
 
         mPreviousContentRectOnWindow.set(mContentRectOnWindow);
     }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index bada791..bd9b014 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1414,7 +1414,7 @@
     <permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
         android:label="@string/permlab_systemAlertWindow"
         android:description="@string/permdesc_systemAlertWindow"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="signature|system|appop" />
 
     <!-- ================================== -->
     <!-- Permissions affecting the system wallpaper -->
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 65da1f1..62131da 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -16,9 +16,12 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24dp"
         android:height="24dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-            android:pathData="M20,8H8c-2.2,0 -4,1.8 -4,4l0,24c0,2.2 1.8,4 4,4h32c2.2,0 4,-1.8 4,-4V16c0,-2.2 -1.8,-4 -4,-4H24L20,8z"
-            android:fillColor="#FFFFFF"/>
+        android:fillColor="#FF000000"
+        android:pathData="M0,0h48v48H0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M27,9c2.2,0 4,-1.8 4,-4s-1.8,-4 -4,-4 -4,1.8 -4,4 1.8,4 4,4zm-7.2,27.8l1.9,-8.8 4.3,4v12h4V28.9l-4.1,-4.1 1.2,-6C29.7,22 33.6,24 38,24v-4c-3.7,0 -6.9,-2 -8.7,-4.9l-1.9,-3.2c-0.7,-1.2 -2,-1.9 -3.4,-1.9 -0.5,0 -1,0.1 -1.5,0.3L12,14.6V24h4v-6.7l3.5,-1.4L16.4,32l-9.8,-1.9 -0.8,3.9s14,2.7 14,2.8z"/>
 </vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4bc2205..451813c 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2258,4 +2258,7 @@
 
     <!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
     <bool name="config_eap_sim_based_auth_supported">true</bool>
+ 
+    <!-- How long history of previous vibrations should be kept for the dumpsys. -->
+    <integer name="config_previousVibrationsDumpLimit">20</integer>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ebbbc4c..01ecba8 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1708,6 +1708,7 @@
   <java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
   <java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
   <java-symbol type="integer" name="config_notificationServiceArchiveSize" />
+  <java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
   <java-symbol type="integer" name="config_radioScanningTimeout" />
   <java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
   <java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 5c55efb8..ea444a4 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.net.IpPrefix;
+import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.RouteInfo;
@@ -26,6 +28,7 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 
+
 public class LinkPropertiesTest extends TestCase {
     private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
     private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
@@ -567,4 +570,80 @@
         assertEquals(ProvisioningChange.STILL_PROVISIONED,
                 LinkProperties.compareProvisioning(v6lp, v6lp2));
     }
+
+    @SmallTest
+    public void testIsReachable() {
+        final LinkProperties v4lp = new LinkProperties();
+        assertFalse(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Add an on-link route, making the on-link DNS server reachable,
+        // but there is still no IPv4 address.
+        assertTrue(v4lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+        assertFalse(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Adding an IPv4 address (right now, any IPv4 address) means we use
+        // the routes to compute likely reachability.
+        assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
+        assertTrue(v4lp.isReachable(DNS1));
+        assertFalse(v4lp.isReachable(DNS2));
+
+        // Adding a default route makes the off-link DNS server reachable.
+        assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
+        assertTrue(v4lp.isReachable(DNS1));
+        assertTrue(v4lp.isReachable(DNS2));
+
+        final LinkProperties v6lp = new LinkProperties();
+        final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
+        final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
+        final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a link-local route, making the link-local DNS servers reachable. Because
+        // we assume the presence of an IPv6 link-local address, link-local DNS servers
+        // are considered reachable, but only those with a non-zero scope identifier.
+        assertTrue(v6lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a link-local address--nothing changes.
+        assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertFalse(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a global route on link, but no global address yet. DNS servers reachable
+        // via a route that doesn't require a gateway: give them the benefit of the
+        // doubt and hope the link-local source address suffices for communication.
+        assertTrue(v6lp.addRoute(new RouteInfo(
+                new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Add a global address; the on-link global address DNS server is (still)
+        // presumed reachable.
+        assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertFalse(v6lp.isReachable(DNS6));
+
+        // Adding a default route makes the off-link DNS server reachable.
+        assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
+        assertFalse(v6lp.isReachable(kLinkLocalDns));
+        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+        assertTrue(v6lp.isReachable(kOnLinkDns));
+        assertTrue(v6lp.isReachable(DNS6));
+    }
 }
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 1a6d34e..91e931d 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -50,6 +50,8 @@
         android:layout_below="@id/volume_row_header"
         android:layout_toEndOf="@id/volume_row_icon"
         android:layout_toStartOf="@+id/volume_settings_button"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
         android:paddingEnd="8dp"
         android:paddingStart="8dp" />
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 81461bd..f432808 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -57,7 +57,7 @@
         return mSelectedValue;
     }
 
-    public void setSelectedValue(Object value) {
+    public void setSelectedValue(Object value, boolean fromClick) {
         if (Objects.equals(value, mSelectedValue)) return;
         mSelectedValue = value;
         for (int i = 0; i < getChildCount(); i++) {
@@ -67,7 +67,7 @@
             c.setSelected(selected);
             c.setTypeface(selected ? MEDIUM : REGULAR);
         }
-        fireOnSelected();
+        fireOnSelected(fromClick);
     }
 
     public void addButton(int labelResId, int contentDescriptionResId, Object value) {
@@ -100,9 +100,9 @@
         }
     }
 
-    private void fireOnSelected() {
+    private void fireOnSelected(boolean fromClick) {
         if (mCallback != null) {
-            mCallback.onSelected(mSelectedValue);
+            mCallback.onSelected(mSelectedValue, fromClick);
         }
     }
 
@@ -115,11 +115,11 @@
     private final View.OnClickListener mClick = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
-            setSelectedValue(v.getTag());
+            setSelectedValue(v.getTag(), true /* fromClick */);
         }
     };
 
     public interface Callback extends Interaction.Callback {
-        void onSelected(Object value);
+        void onSelected(Object value, boolean fromClick);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 0ab0392..3964820 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -741,12 +741,7 @@
 
     private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
         if (isActive && mExpanded) {
-            row.slider.setFocusable(true);
-            row.slider.setFocusableInTouchMode(true);
             row.slider.requestFocus();
-        } else {
-            row.slider.setFocusableInTouchMode(false);
-            row.slider.setFocusable(false);
         }
         final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
                 : mInactiveSliderTint;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 8035cd3..3c9a7fc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -391,7 +391,7 @@
             setExpanded(isShown());
             mSessionZen = zen;
         }
-        mZenButtons.setSelectedValue(zen);
+        mZenButtons.setSelectedValue(zen, false /* fromClick */);
         updateWidgets();
         handleUpdateConditions();
         if (mExpanded) {
@@ -968,10 +968,12 @@
 
     private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
         @Override
-        public void onSelected(final Object value) {
+        public void onSelected(final Object value, boolean fromClick) {
             if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
                 final int zen = (Integer) value;
-                MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+                if (fromClick) {
+                    MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+                }
                 if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
                 final Uri realConditionId = getRealConditionId(mSessionExitCondition);
                 AsyncTask.execute(new Runnable() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 47971a1..7f124dc 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -140,14 +140,12 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -2713,7 +2711,10 @@
         } else {
             nai = getNetworkAgentInfoForNetwork(network);
         }
-        if (nai == null) return;
+        if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
+            nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
+            return;
+        }
         // Revalidate if the app report does not match our current validated state.
         if (hasConnectivity == nai.lastValidated) return;
         final int uid = Binder.getCallingUid();
@@ -4014,51 +4015,10 @@
         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
     }
 
-    // TODO: investigate moving this into LinkProperties, if only to make more accurate
-    // the isProvisioned() checks.
-    private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) {
-        final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>();
-        final List<RouteInfo> allRoutes = lp.getAllRoutes();
-        for (InetAddress nameserver : lp.getDnsServers()) {
-            // If the LinkProperties doesn't include a route to the nameserver, ignore it.
-            final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver);
-            if (bestRoute == null) {
-                continue;
-            }
-
-            // TODO: better source address evaluation for destination addresses.
-            if (nameserver instanceof Inet4Address) {
-                if (!lp.hasIPv4Address()) {
-                    continue;
-                }
-            } else if (nameserver instanceof Inet6Address) {
-                if (nameserver.isLinkLocalAddress()) {
-                    if (((Inet6Address)nameserver).getScopeId() == 0) {
-                        // For now, just make sure link-local DNS servers have
-                        // scopedIds set, since DNS lookups will fail otherwise.
-                        // TODO: verify the scopeId matches that of lp's interface.
-                        continue;
-                    }
-                }  else {
-                    if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) {
-                        // TODO: reconsider all corner cases (disconnected ULA networks, ...).
-                        continue;
-                    }
-                }
-            }
-
-            dnsServers.add(nameserver);
-        }
-        return Collections.unmodifiableList(dnsServers);
-    }
-
     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
                              boolean flush, boolean useDefaultDns) {
-        // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the
-        // route to a DNS server has been removed (only really applicable in special cases
-        // where there is no default route).
         if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
-            Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp);
+            Collection<InetAddress> dnses = newLp.getDnsServers();
             if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
                 dnses = new ArrayList();
                 dnses.add(mDefaultDns);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ebbd9e5..42794e7 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -79,6 +79,7 @@
         void setCredential(String credential, String savedCredential, int userId)
                 throws RemoteException;
         byte[] toHash(String credential, int userId);
+        String adjustForKeystore(String credential);
     }
 
     public LockSettingsService(Context context) {
@@ -528,6 +529,11 @@
                        return LockPatternUtils.patternToHash(
                                LockPatternUtils.stringToPattern(pattern));
                    }
+
+                   @Override
+                   public String adjustForKeystore(String pattern) {
+                       return LockPatternUtils.patternStringToBaseZero(pattern);
+                   }
                }
        );
 
@@ -568,6 +574,11 @@
                    public byte[] toHash(String password, int userId) {
                        return mLockPatternUtils.passwordToHash(password, userId);
                    }
+
+                   @Override
+                   public String adjustForKeystore(String password) {
+                       return password;
+                   }
                }
        );
     }
@@ -587,7 +598,7 @@
         if (storedHash.version == CredentialHash.VERSION_LEGACY) {
             byte[] hash = credentialUtil.toHash(credential, userId);
             if (Arrays.equals(hash, storedHash.hash)) {
-                unlockKeystore(credential, userId);
+                unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
                 // migrate credential to GateKeeper
                 credentialUtil.setCredential(credential, null, userId);
                 if (!hasChallenge) {
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 20f6f1c..30f4dce 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -47,7 +47,10 @@
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.ListIterator;
@@ -58,6 +61,8 @@
     private static final boolean DEBUG = false;
 
     private final LinkedList<Vibration> mVibrations;
+    private final LinkedList<VibrationInfo> mPreviousVibrations;
+    private final int mPreviousVibrationsLimit;
     private Vibration mCurrentVibration;
     private final WorkSource mTmpWorkSource = new WorkSource();
     private final Handler mH = new Handler();
@@ -146,6 +151,47 @@
         }
     }
 
+    private static class VibrationInfo {
+        long timeout;
+        long startTime;
+        long[] pattern;
+        int repeat;
+        int usageHint;
+        int uid;
+        String opPkg;
+
+        public VibrationInfo(long timeout, long startTime, long[] pattern, int repeat,
+                int usageHint, int uid, String opPkg) {
+            this.timeout = timeout;
+            this.startTime = startTime;
+            this.pattern = pattern;
+            this.repeat = repeat;
+            this.usageHint = usageHint;
+            this.uid = uid;
+            this.opPkg = opPkg;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("timeout: ")
+                    .append(timeout)
+                    .append(", startTime: ")
+                    .append(startTime)
+                    .append(", pattern: ")
+                    .append(Arrays.toString(pattern))
+                    .append(", repeat: ")
+                    .append(repeat)
+                    .append(", usageHint: ")
+                    .append(usageHint)
+                    .append(", uid: ")
+                    .append(uid)
+                    .append(", opPkg: ")
+                    .append(opPkg)
+                    .toString();
+        }
+    }
+
     VibratorService(Context context) {
         // Reset the hardware to a default state, in case this is a runtime
         // restart instead of a fresh boot.
@@ -161,7 +207,11 @@
         mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                 BatteryStats.SERVICE_NAME));
 
-        mVibrations = new LinkedList<Vibration>();
+        mPreviousVibrationsLimit = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_previousVibrationsDumpLimit);
+
+        mVibrations = new LinkedList<>();
+        mPreviousVibrations = new LinkedList<>();
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -252,6 +302,7 @@
                 removeVibrationLocked(token);
                 doCancelVibrateLocked();
                 mCurrentVibration = vib;
+                addToPreviousVibrationsLocked(vib);
                 startVibrationLocked(vib);
             }
         } finally {
@@ -315,6 +366,7 @@
                     mCurrentVibration = vib;
                     startVibrationLocked(vib);
                 }
+                addToPreviousVibrationsLocked(vib);
             }
         }
         finally {
@@ -322,6 +374,14 @@
         }
     }
 
+    private void addToPreviousVibrationsLocked(Vibration vib) {
+        if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
+            mPreviousVibrations.removeFirst();
+        }
+        mPreviousVibrations.addLast(new VibratorService.VibrationInfo(vib.mTimeout, vib.mStartTime,
+                vib.mPattern, vib.mRepeat, vib.mUsageHint, vib.mUid, vib.mOpPkg));
+    }
+
     @Override // Binder call
     public void cancelVibrate(IBinder token) {
         mContext.enforceCallingOrSelfPermission(
@@ -649,7 +709,6 @@
                 if (!mDone) {
                     // If this vibration finished naturally, start the next
                     // vibration.
-                    mVibrations.remove(mVibration);
                     unlinkVibration(mVibration);
                     startNextVibrationLocked();
                 }
@@ -685,4 +744,23 @@
             }
         }
     };
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+
+            pw.println("Permission Denial: can't dump vibrator service from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+        pw.println("Previous vibrations:");
+        synchronized (mVibrations) {
+            for (VibrationInfo info : mPreviousVibrations) {
+                pw.print("  ");
+                pw.println(info.toString());
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 93ed2ee..2c57833 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -23,12 +23,14 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
+import android.content.Intent;
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
 import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
 import android.net.Uri;
@@ -161,8 +163,9 @@
      * Register a content observer tied to a specific user's view of the provider.
      * @param userHandle the user whose view of the provider is to be observed.  May be
      *     the calling user without requiring any permission, otherwise the caller needs to
-     *     hold the INTERACT_ACROSS_USERS_FULL permission.  Pseudousers USER_ALL and
-     *     USER_CURRENT are properly handled; all other pseudousers are forbidden.
+     *     hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
+     *     Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
+     *     are forbidden.
      */
     @Override
     public void registerContentObserver(Uri uri, boolean notifyForDescendants,
@@ -171,8 +174,17 @@
             throw new IllegalArgumentException("You must pass a valid uri and observer");
         }
 
-        enforceCrossUserPermission(userHandle,
-                "no permission to observe other users' provider view");
+        final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // Registering an observer for any user other than the calling user requires uri grant or
+        // cross user permission
+        if (callingUserHandle != userHandle &&
+                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                        != PackageManager.PERMISSION_GRANTED) {
+            enforceCrossUserPermission(userHandle,
+                    "no permission to observe other users' provider view");
+        }
 
         if (userHandle < 0) {
             if (userHandle == UserHandle.USER_CURRENT) {
@@ -185,7 +197,7 @@
 
         synchronized (mRootNode) {
             mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
-                    Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
+                    uid, pid, userHandle);
             if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
                     " with notifyForDescendants " + notifyForDescendants);
         }
@@ -211,8 +223,9 @@
      * Notify observers of a particular user's view of the provider.
      * @param userHandle the user whose view of the provider is to be notified.  May be
      *     the calling user without requiring any permission, otherwise the caller needs to
-     *     hold the INTERACT_ACROSS_USERS_FULL permission.  Pseudousers USER_ALL and
-     *     USER_CURRENT are properly interpreted; no other pseudousers are allowed.
+     *     hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
+     *     Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
+     *     allowed.
      */
     @Override
     public void notifyChange(Uri uri, IContentObserver observer,
@@ -223,11 +236,14 @@
                     + " from observer " + observer + ", syncToNetwork " + syncToNetwork);
         }
 
-        // Notify for any user other than the caller's own requires permission.
+        final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
         final int callingUserHandle = UserHandle.getCallingUserId();
-        if (userHandle != callingUserHandle) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
-                    "no permission to notify other users");
+        // Notify for any user other than the caller requires uri grant or cross user permission
+        if (callingUserHandle != userHandle &&
+                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                        != PackageManager.PERMISSION_GRANTED) {
+            enforceCrossUserPermission(userHandle, "no permission to notify other users");
         }
 
         // We passed the permission check; resolve pseudouser targets as appropriate
@@ -240,7 +256,6 @@
             }
         }
 
-        final int uid = Binder.getCallingUid();
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         long identityToken = clearCallingIdentity();
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 751bae9..04dce3a 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -117,7 +117,7 @@
 
     private static final Set<String> ACCOUNTS_PERMISSIONS = new ArraySet<>();
     static {
-        ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
+        //ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
     }
 
     private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d31c6e9..b41dd06 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,6 +51,7 @@
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.media.session.MediaSessionLegacyHelper;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.FactoryTest;
@@ -61,6 +62,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -267,6 +269,7 @@
     SearchManager mSearchManager;
     AccessibilityManager mAccessibilityManager;
     BurnInProtectionHelper mBurnInProtectionHelper;
+    AppOpsManager mAppOpsManager;
 
     // Vibrator pattern for haptic feedback of a long press.
     long[] mLongPressVibePattern;
@@ -1255,6 +1258,7 @@
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
 
         // Init display burn-in protection
         boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -1812,6 +1816,25 @@
                 permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
         }
         if (permission != null) {
+            if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
+                final int callingUid = Binder.getCallingUid();
+                // check if this is a system uid first before bothering with
+                // obtaining package name
+                if (callingUid == Process.SYSTEM_UID) {
+                    return WindowManagerGlobal.ADD_OKAY;
+                }
+
+                final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid,
+                        attrs.packageName);
+                if (mode == AppOpsManager.MODE_DEFAULT) {
+                    if (mContext.checkCallingPermission(permission) !=
+                            PackageManager.PERMISSION_GRANTED) {
+                        return WindowManagerGlobal.ADD_PERMISSION_DENIED;
+                    }
+                }
+                return WindowManagerGlobal.ADD_OKAY;
+            }
+
             if (mContext.checkCallingOrSelfPermission(permission)
                     != PackageManager.PERMISSION_GRANTED) {
                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5cfbb40..0670cd2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -225,6 +225,7 @@
     private static final Set<String> SECURE_SETTINGS_WHITELIST;
     private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
     private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
+    private static final Set<String> GLOBAL_SETTINGS_DEPRECATED;
     static {
         SECURE_SETTINGS_WHITELIST = new HashSet();
         SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
@@ -240,13 +241,17 @@
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING);
-        GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
-        GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.MODE_RINGER);
-        GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.NETWORK_PREFERENCE);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
+
+        GLOBAL_SETTINGS_DEPRECATED = new HashSet();
+        GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
+        GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+        GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.MODE_RINGER);
+        GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.NETWORK_PREFERENCE);
+        GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
     }
 
     // Keyguard features that when set of a profile will affect the profiles
@@ -5954,14 +5959,16 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
+            // Some settings are no supported any more. However we do not want to throw a
+            // SecurityException to avoid breaking apps.
+            if (GLOBAL_SETTINGS_DEPRECATED.contains(setting)) {
+                Log.i(LOG_TAG, "Global setting no longer supported: " + setting);
+                return;
+            }
+
             if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
-                // BLUETOOTH_ON and WIFI_ON used to be supported but not any more. We do not want to
-                // throw a SecurityException not to break apps.
-                if (!Settings.Global.BLUETOOTH_ON.equals(setting)
-                        && !Settings.Global.WIFI_ON.equals(setting)) {
-                    throw new SecurityException(String.format(
-                            "Permission denial: device owners cannot update %1$s", setting));
-                }
+                throw new SecurityException(String.format(
+                        "Permission denial: device owners cannot update %1$s", setting));
             }
 
             if (Settings.Global.STAY_ON_WHILE_PLUGGED_IN.equals(setting)) {