Merge "Fix incorrect default wifi power draw values" into mnc-dev
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3e4a66d..9c401c7f 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -138,7 +138,9 @@
                     new AccountAuthenticatorResponse(response),
                         accountType, authTokenType, features, options);
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    result.keySet(); // force it to be unparcelled
+                    if (result != null) {
+                        result.keySet(); // force it to be unparcelled
+                    }
                     Log.v(TAG, "addAccount: result " + AccountManager.sanitizeResult(result));
                 }
                 if (result != null) {
@@ -160,7 +162,9 @@
                 final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials(
                     new AccountAuthenticatorResponse(response), account, options);
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    result.keySet(); // force it to be unparcelled
+                    if (result != null) {
+                        result.keySet(); // force it to be unparcelled
+                    }
                     Log.v(TAG, "confirmCredentials: result "
                             + AccountManager.sanitizeResult(result));
                 }
@@ -185,7 +189,9 @@
                 result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL,
                         AbstractAccountAuthenticator.this.getAuthTokenLabel(authTokenType));
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    result.keySet(); // force it to be unparcelled
+                    if (result != null) {
+                        result.keySet(); // force it to be unparcelled
+                    }
                     Log.v(TAG, "getAuthTokenLabel: result "
                             + AccountManager.sanitizeResult(result));
                 }
@@ -209,7 +215,9 @@
                         new AccountAuthenticatorResponse(response), account,
                         authTokenType, loginOptions);
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    result.keySet(); // force it to be unparcelled
+                    if (result != null) {
+                        result.keySet(); // force it to be unparcelled
+                    }
                     Log.v(TAG, "getAuthToken: result " + AccountManager.sanitizeResult(result));
                 }
                 if (result != null) {
@@ -234,7 +242,10 @@
                     new AccountAuthenticatorResponse(response), account,
                         authTokenType, loginOptions);
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    result.keySet(); // force it to be unparcelled
+                    // Result may be null.
+                    if (result != null) {
+                        result.keySet(); // force it to be unparcelled
+                    }
                     Log.v(TAG, "updateCredentials: result "
                             + AccountManager.sanitizeResult(result));
                 }
@@ -490,7 +501,7 @@
      * <ul>
      * <li> {@link AccountManager#KEY_INTENT}, or
      * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of
-     * the account that was added, or
+     * the account whose credentials were updated, or
      * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
      * indicate an error
      * </ul>
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 9394d2c..8c84b4d 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -333,7 +333,7 @@
         try {
             return mService.getPassword(account);
         } catch (RemoteException e) {
-            // will never happen
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
@@ -362,7 +362,7 @@
         try {
             return mService.getUserData(account, key);
         } catch (RemoteException e) {
-            // will never happen
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
@@ -415,8 +415,10 @@
      *
      * <p>It is safe to call this method from the main thread.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS}.
+     * <p>Clients of this method that have not been granted the
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+     * will only see those accounts managed by AbstractAccountAuthenticators whose
+     * signature matches the client.
      *
      * @return An array of {@link Account}, one for each account.  Empty
      *     (never null) if no accounts have been added.
@@ -438,8 +440,10 @@
      *
      * <p>It is safe to call this method from the main thread.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS}.
+     * <p>Clients of this method that have not been granted the
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+     * will only see those accounts managed by AbstractAccountAuthenticators whose
+     * signature matches the client.
      *
      * @return An array of {@link Account}, one for each account.  Empty
      *     (never null) if no accounts have been added.
@@ -466,7 +470,7 @@
         try {
             return mService.getAccountsForPackage(packageName, uid);
         } catch (RemoteException re) {
-            // possible security exception
+            // won't ever happen
             throw new RuntimeException(re);
         }
     }
@@ -483,7 +487,7 @@
         try {
             return mService.getAccountsByTypeForPackage(type, packageName);
         } catch (RemoteException re) {
-            // possible security exception
+            // won't ever happen
             throw new RuntimeException(re);
         }
     }
@@ -497,9 +501,10 @@
      *
      * <p>It is safe to call this method from the main thread.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
-     * authenticator that owns the account type.
+     * <p>Clients of this method that have not been granted the
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+     * will only see those accounts managed by AbstractAccountAuthenticators whose
+     * signature matches the client.
      *
      * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
      * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
@@ -585,7 +590,8 @@
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
      * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS}.
+     * {@link android.Manifest.permission#GET_ACCOUNTS} or be a signature
+     * match with the AbstractAccountAuthenticator that manages the account.
      *
      * @param account The {@link Account} to test
      * @param features An array of the account features to check
@@ -628,9 +634,10 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
-     * authenticator that owns the account type.
+     * <p>Clients of this method that have not been granted the
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+     * will only see those accounts managed by AbstractAccountAuthenticators whose
+     * signature matches the client.
      *
      * @param type The type of accounts to return, must not be null
      * @param features An array of the account features to require,
@@ -701,7 +708,7 @@
         try {
             return mService.addAccountExplicitly(account, password, userdata);
         } catch (RemoteException e) {
-            // won't ever happen
+            // Can happen if there was a SecurityException was thrown.
             throw new RuntimeException(e);
         }
     }
@@ -966,7 +973,7 @@
         try {
             return mService.removeAccountExplicitly(account);
         } catch (RemoteException e) {
-            // won't ever happen
+            // May happen if the caller doesn't match the signature of the authenticator.
             throw new RuntimeException(e);
         }
     }
@@ -1114,7 +1121,7 @@
         try {
             mService.setUserData(account, key, value);
         } catch (RemoteException e) {
-            // won't ever happen
+            // Will happen if there is not signature match.
             throw new RuntimeException(e);
         }
     }
@@ -1733,7 +1740,7 @@
      *     with these fields if an activity was supplied and the account
      *     credentials were successfully updated:
      * <ul>
-     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account created
+     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account
      * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
      * </ul>
      *
@@ -2501,10 +2508,12 @@
      * listeners are added in an Activity or Service's {@link Activity#onCreate}
      * and removed in {@link Activity#onDestroy}.
      *
-     * <p>It is safe to call this method from the main thread.
+     * <p>The listener will only be informed of accounts that would be returned
+     * to the caller via {@link #getAccounts()}. Typically this means that to
+     * get any accounts, the caller will need to be grated the GET_ACCOUNTS
+     * permission.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS}.
+     * <p>It is safe to call this method from the main thread.
      *
      * @param listener The listener to send notifications to
      * @param handler {@link Handler} identifying the thread to use
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f21422e..2d729c7 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -165,13 +165,19 @@
 
     /**
      * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
-     * allows a mobile device management application which starts managed provisioning to pass data
-     * to itself.
+     * allows a mobile device management application or NFC programmer application which starts
+     * managed provisioning to pass data to the management application instance after provisioning.
      * <p>
      * If used with {@link #ACTION_PROVISION_MANAGED_PROFILE} it can be used by the application that
      * sends the intent to pass data to itself on the newly created profile.
      * If used with {@link #ACTION_PROVISION_MANAGED_DEVICE} it allows passing data to the same
      * instance of the app on the primary user.
+     * Starting from {@link android.os.Build.VERSION_CODES#M}, if used with
+     * {@link #MIME_TYPE_PROVISIONING_NFC} as part of NFC managed device provisioning, the NFC
+     * message should contain a stringified {@link java.util.Properties} instance, whose string
+     * properties will be converted into a {@link android.os.PersistableBundle} and passed to the
+     * management application after provisioning.
+     *
      * <p>
      * In both cases the application receives the data in
      * {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
@@ -587,7 +593,9 @@
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional, supported from
+     * {@link android.os.Build.VERSION_CODES#M} </li></ul>
      *
      * <p>
      * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index aaaa745..ec443cd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1782,14 +1782,6 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
     /**
-     * Sync State Changed Action: This is broadcast when the sync starts or stops or when one has
-     * been failing for a long time.  It is used by the SyncManager and the StatusBar service.
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_SYNC_STATE_CHANGED
-            = "android.intent.action.SYNC_STATE_CHANGED";
-    /**
      * Broadcast Action: This is broadcast once, after the system has finished
      * booting.  It can be used to perform application-specific initialization,
      * such as installing alarms.  You must hold the
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 9548d49..2620571 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -16,6 +16,8 @@
 
 package android.content.res;
 
+import android.annotation.NonNull;
+
 import java.util.Objects;
 
 /** @hide */
@@ -25,27 +27,27 @@
     private final int mHash;
 
     public final int mDisplayId;
+    @NonNull
     public final Configuration mOverrideConfiguration;
 
     public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
             float scale) {
         mResDir = resDir;
         mDisplayId = displayId;
-        mOverrideConfiguration = overrideConfiguration;
+        mOverrideConfiguration = overrideConfiguration != null
+                ? overrideConfiguration : Configuration.EMPTY;
         mScale = scale;
 
         int hash = 17;
         hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
         hash = 31 * hash + mDisplayId;
-        hash = 31 * hash + (mOverrideConfiguration != null
-                ? mOverrideConfiguration.hashCode() : 0);
+        hash = 31 * hash + mOverrideConfiguration.hashCode();
         hash = 31 * hash + Float.floatToIntBits(mScale);
         mHash = hash;
     }
 
     public boolean hasOverrideConfiguration() {
-        return mOverrideConfiguration != null
-                && !Configuration.EMPTY.equals(mOverrideConfiguration);
+        return !Configuration.EMPTY.equals(mOverrideConfiguration);
     }
 
     @Override
@@ -66,13 +68,8 @@
         if (mDisplayId != peer.mDisplayId) {
             return false;
         }
-        if (mOverrideConfiguration != peer.mOverrideConfiguration) {
-            if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
-                return false;
-            }
-            if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
-                return false;
-            }
+        if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
+            return false;
         }
         if (mScale != peer.mScale) {
             return false;
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 80c7b1a..6e4c9de 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -97,9 +97,6 @@
      */
     void setUsbDataUnlocked(boolean unlock);
 
-    /* Returns true iff sensitive user data is exposed on the USB connection. */
-    boolean isUsbDataUnlocked();
-
     /* Allow USB debugging from the attached host. If alwaysAllow is true, add the
      * the public key to list of host keys that the user has approved.
      */
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index c88f213..3b3ee52 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -520,21 +520,6 @@
     }
 
     /**
-     * Returns {@code true} iff access to sensitive USB data is currently allowed when
-     * in device mode.
-     *
-     * {@hide}
-     */
-    public boolean isUsbDataUnlocked() {
-        try {
-            return mService.isUsbDataUnlocked();
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException in isUsbDataUnlocked", e);
-        }
-        return false;
-    }
-
-    /**
      * Returns a list of physical USB ports on the device.
      * <p>
      * This list is guaranteed to contain all dual-role USB Type C ports but it might
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index abed1f0..605acb0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -964,41 +964,6 @@
         return 1;
     }
 
-    /**
-     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
-     * NetworkCapabilities object if all the capabilities it provides are
-     * typically provided by restricted networks.
-     *
-     * TODO: consider:
-     * - Moving to NetworkCapabilities
-     * - Renaming it to guessRestrictedCapability and make it set the
-     *   restricted capability bit in addition to clearing it.
-     * @hide
-     */
-    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
-        for (int capability : nc.getCapabilities()) {
-            switch (capability) {
-                case NetworkCapabilities.NET_CAPABILITY_CBS:
-                case NetworkCapabilities.NET_CAPABILITY_DUN:
-                case NetworkCapabilities.NET_CAPABILITY_EIMS:
-                case NetworkCapabilities.NET_CAPABILITY_FOTA:
-                case NetworkCapabilities.NET_CAPABILITY_IA:
-                case NetworkCapabilities.NET_CAPABILITY_IMS:
-                case NetworkCapabilities.NET_CAPABILITY_RCS:
-                case NetworkCapabilities.NET_CAPABILITY_XCAP:
-                case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
-                    continue;
-                default:
-                    // At least one capability usually provided by unrestricted
-                    // networks. Conclude that this network is unrestricted.
-                    return;
-            }
-        }
-        // All the capabilities are typically provided by restricted networks.
-        // Conclude that this network is restricted.
-        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-    }
-
     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
         if (networkType == TYPE_MOBILE) {
             int cap = -1;
@@ -1021,14 +986,14 @@
             }
             NetworkCapabilities netCap = new NetworkCapabilities();
             netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
-            maybeMarkCapabilitiesRestricted(netCap);
+            netCap.maybeMarkCapabilitiesRestricted();
             return netCap;
         } else if (networkType == TYPE_WIFI) {
             if ("p2p".equals(feature)) {
                 NetworkCapabilities netCap = new NetworkCapabilities();
                 netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
                 netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
-                maybeMarkCapabilitiesRestricted(netCap);
+                netCap.maybeMarkCapabilitiesRestricted();
                 return netCap;
             }
         }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 651fb35..29b063a 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -38,10 +38,7 @@
      */
     public NetworkCapabilities() {
         clearAll();
-        mNetworkCapabilities =
-                (1 << NET_CAPABILITY_NOT_RESTRICTED) |
-                (1 << NET_CAPABILITY_TRUSTED) |
-                (1 << NET_CAPABILITY_NOT_VPN);
+        mNetworkCapabilities = DEFAULT_CAPABILITIES;
     }
 
     public NetworkCapabilities(NetworkCapabilities nc) {
@@ -187,6 +184,28 @@
     private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;
 
     /**
+     * Capabilities that are set by default when the object is constructed.
+     */
+    private static final long DEFAULT_CAPABILITIES =
+            (1 << NET_CAPABILITY_NOT_RESTRICTED) |
+            (1 << NET_CAPABILITY_TRUSTED) |
+            (1 << NET_CAPABILITY_NOT_VPN);
+
+    /**
+     * Capabilities that suggest that a network is restricted.
+     * {@see #maybeMarkCapabilitiesRestricted}.
+     */
+    private static final long RESTRICTED_CAPABILITIES =
+            (1 << NET_CAPABILITY_CBS) |
+            (1 << NET_CAPABILITY_DUN) |
+            (1 << NET_CAPABILITY_EIMS) |
+            (1 << NET_CAPABILITY_FOTA) |
+            (1 << NET_CAPABILITY_IA) |
+            (1 << NET_CAPABILITY_IMS) |
+            (1 << NET_CAPABILITY_RCS) |
+            (1 << NET_CAPABILITY_XCAP);
+
+    /**
      * Adds the given capability to this {@code NetworkCapability} instance.
      * Multiple capabilities may be applied sequentially.  Note that when searching
      * for a network to satisfy a request, all capabilities requested must be satisfied.
@@ -269,6 +288,22 @@
     }
 
     /**
+     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
+     * typically provided by restricted networks.
+     *
+     * TODO: consider:
+     * - Renaming it to guessRestrictedCapability and make it set the
+     *   restricted capability bit in addition to clearing it.
+     * @hide
+     */
+    public void maybeMarkCapabilitiesRestricted() {
+        // If all the capabilities are typically provided by restricted networks, conclude that this
+        // network is restricted.
+        if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
+            removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+    }
+
+    /**
      * Representing the transport type.  Apps should generally not care about transport.  A
      * request for a fast internet connection could be satisfied by a number of different
      * transports.  If any are specified here it will be satisfied a Network that matches
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index e61594c..e184ec4 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -83,7 +83,13 @@
          * Build {@link NetworkRequest} give the current set of capabilities.
          */
         public NetworkRequest build() {
-            return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+            // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
+            // when later an unrestricted capability could be added to mNetworkCapabilities, in
+            // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
+            // maybeMarkCapabilitiesRestricted() doesn't add back.
+            final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
+            nc.maybeMarkCapabilitiesRestricted();
+            return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
                     ConnectivityManager.REQUEST_ID_UNSET);
         }
 
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 8114155..cd84c8f 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -388,8 +388,10 @@
 
     /**
      * Setup a new physical network.
+     * @param permission null if no permissions required to access this network.  PERMISSION_NETWORK
+     *                   or PERMISSION_SYSTEM to set respective permission.
      */
-    void createPhysicalNetwork(int netId);
+    void createPhysicalNetwork(int netId, String permission);
 
     /**
      * Setup a new VPN.
@@ -416,6 +418,13 @@
     void setDefaultNetId(int netId);
     void clearDefaultNetId();
 
+    /**
+     * Set permission for a network.
+     * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
+     *                   permission.
+     */
+    void setNetworkPermission(int netId, String permission);
+
     void setPermission(String permission, in int[] uids);
     void clearPermission(in int[] uids);
 
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 23555d6..4f880b1 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -421,7 +421,7 @@
                 int presentation, int callType, int features, PhoneAccountHandle accountHandle,
                 long start, int duration, Long dataUsage) {
             return addCall(ci, context, number, presentation, callType, features, accountHandle,
-                    start, duration, dataUsage, false);
+                    start, duration, dataUsage, false, false);
         }
 
 
@@ -450,8 +450,41 @@
          * {@hide}
          */
         public static Uri addCall(CallerInfo ci, Context context, String number,
+                                  int presentation, int callType, int features, PhoneAccountHandle accountHandle,
+                                  long start, int duration, Long dataUsage, boolean addForAllUsers) {
+            return addCall(ci, context, number, presentation, callType, features, accountHandle,
+                    start, duration, dataUsage, addForAllUsers, false);
+        }
+
+        /**
+         * Adds a call to the call log.
+         *
+         * @param ci the CallerInfo object to get the target contact from.  Can be null
+         * if the contact is unknown.
+         * @param context the context used to get the ContentResolver
+         * @param number the phone number to be added to the calls db
+         * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+         *        is set by the network and denotes the number presenting rules for
+         *        "allowed", "payphone", "restricted" or "unknown"
+         * @param callType enumerated values for "incoming", "outgoing", or "missed"
+         * @param features features of the call (e.g. Video).
+         * @param accountHandle The accountHandle object identifying the provider of the call
+         * @param start time stamp for the call in milliseconds
+         * @param duration call duration in seconds
+         * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
+         *                  the call.
+         * @param addForAllUsers If true, the call is added to the call log of all currently
+         *        running users. The caller must have the MANAGE_USERS permission if this is true.
+         * @param is_read Flag to show if the missed call log has been read by the user or not.
+         *                Used for call log restore of missed calls.
+         *
+         * @result The URI of the call log entry belonging to the user that made or received this
+         *        call.
+         * {@hide}
+         */
+        public static Uri addCall(CallerInfo ci, Context context, String number,
                 int presentation, int callType, int features, PhoneAccountHandle accountHandle,
-                long start, int duration, Long dataUsage, boolean addForAllUsers) {
+                long start, int duration, Long dataUsage, boolean addForAllUsers, boolean is_read) {
             final ContentResolver resolver = context.getContentResolver();
             int numberPresentation = PRESENTATION_ALLOWED;
 
@@ -516,7 +549,7 @@
             values.put(NEW, Integer.valueOf(1));
 
             if (callType == MISSED_TYPE) {
-                values.put(IS_READ, Integer.valueOf(0));
+                values.put(IS_READ, Integer.valueOf(is_read ? 1 : 0));
             }
 
             if ((ci != null) && (ci.contactIdOrZero > 0)) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index fa015b2..c3aed75 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -40,6 +40,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.MissingResourceException;
@@ -247,7 +248,7 @@
      * @return A list of features supported for the given language.
      */
     protected Set<String> onGetFeaturesForLanguage(String lang, String country, String variant) {
-        return null;
+        return new HashSet<String>();
     }
 
     private int getExpectedLanguageAvailableStatus(Locale locale) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 928fe93..6e93a30 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3159,6 +3159,17 @@
         return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
     }
 
+    private static void forceLayout(View view) {
+        view.forceLayout();
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+            final int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                forceLayout(group.getChildAt(i));
+            }
+        }
+    }
+
     private final static int MSG_INVALIDATE = 1;
     private final static int MSG_INVALIDATE_RECT = 2;
     private final static int MSG_DIE = 3;
@@ -3297,6 +3308,10 @@
                         mReportNextDraw = true;
                     }
 
+                    if (mView != null) {
+                        forceLayout(mView);
+                    }
+
                     requestLayout();
                 }
                 break;
@@ -3311,6 +3326,9 @@
                     mWinFrame.top = t;
                     mWinFrame.bottom = t + h;
 
+                    if (mView != null) {
+                        forceLayout(mView);
+                    }
                     requestLayout();
                 }
                 break;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4f42ed9..6c7e298 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -7674,6 +7674,7 @@
             final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
 
             long leftOverRxTimeMs = rxTimeMs;
+            long leftOverTxTimeMs = txTimeMs;
 
             if (DEBUG_ENERGY) {
                 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
@@ -7705,6 +7706,10 @@
                 Slog.d(TAG, "  !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
                         + rxTimeMs + " ms). Normalizing scan time.");
             }
+            if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
+                Slog.d(TAG, "  !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
+                        + txTimeMs + " ms). Normalizing scan time.");
+            }
 
             // Actually assign and distribute power usage to apps.
             for (int i = 0; i < uidStatsSize; i++) {
@@ -7716,23 +7721,34 @@
                     // Set the new mark so that next time we get new data since this point.
                     uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
 
+                    long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
+                    long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
+
+                    // Our total scan time is more than the reported Tx/Rx time.
+                    // This is possible because the cost of a scan is approximate.
+                    // Let's normalize the result so that we evenly blame each app
+                    // scanning.
+                    //
+                    // This means that we may have apps that transmitted/received packets not be
+                    // blamed for this, but this is fine as scans are relatively more expensive.
                     if (totalScanTimeMs > rxTimeMs) {
-                        // Our total scan time is more than the reported Rx time.
-                        // This is possible because the cost of a scan is approximate.
-                        // Let's normalize the result so that we evenly blame each app
-                        // scanning.
-                        //
-                        // This means that we may have apps that received packets not be blamed
-                        // for this, but this is fine as scans are relatively more expensive.
-                        scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
+                        scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
+                                totalScanTimeMs;
+                    }
+                    if (totalScanTimeMs > txTimeMs) {
+                        scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
+                                totalScanTimeMs;
                     }
 
                     if (DEBUG_ENERGY) {
-                        Slog.d(TAG, "  ScanTime for UID " + uid.getUid() + ": "
-                                + scanTimeSinceMarkMs + " ms)");
+                        Slog.d(TAG, "  ScanTime for UID " + uid.getUid() + ": Rx:"
+                                + scanRxTimeSinceMarkMs + " ms  Tx:"
+                                + scanTxTimeSinceMarkMs + " ms)");
                     }
-                    uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
-                    leftOverRxTimeMs -= scanTimeSinceMarkMs;
+                    uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanRxTimeSinceMarkMs);
+                    uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, scanTxTimeSinceMarkMs);
+                    leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
+                    leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
                 }
 
                 // Distribute evenly the power consumed while Idle to each app holding a WiFi
@@ -7755,12 +7771,14 @@
 
             if (DEBUG_ENERGY) {
                 Slog.d(TAG, "  New RxPower: " + leftOverRxTimeMs + " ms");
+                Slog.d(TAG, "  New TxPower: " + leftOverTxTimeMs + " ms");
             }
 
-            // Distribute the Tx power appropriately between all apps that transmitted packets.
+            // Distribute the remaining Tx power appropriately between all apps that transmitted
+            // packets.
             for (int i = 0; i < txPackets.size(); i++) {
                 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
-                final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
+                final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets;
                 if (DEBUG_ENERGY) {
                     Slog.d(TAG, "  TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
                 }
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 3181017..39458f9 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -17,10 +17,13 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# Use full Noto Sans Japanese font on non-smaller footprints
+# Use full Noto Sans Japanese font on the normal footprints, but
+# exclude it from SMALLER and use a subset on the CONSTRAINED ones.
 ifneq ($(SMALLER_FONT_FOOTPRINT),true)
+ifneq ($(CONSTRAINED_FONT_FOOTPRINT),true)
 FONT_NOTOSANS_JP_FULL := true
 endif
+endif
 
 ##########################################
 # create symlink for given font
@@ -82,19 +85,32 @@
 extra_font_files :=
 
 ################################
-# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT build
+# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT builds,
+# and the full font on CONSTRAINED_FONT_FOOTPRINT ones.
 ifeq ($(SMALLER_FONT_FOOTPRINT),true)
+droidsans_fallback_src := DroidSansFallback.ttf
+build_droidsans_fallback := true
+endif  # SMALLER_FONT_FOOTPRINT
+
+ifeq ($(CONSTRAINED_FONT_FOOTPRINT),true)
+droidsans_fallback_src := DroidSansFallbackFull.ttf
+build_droidsans_fallback := true
+endif  # CONSTRAINED_FONT_FOOTPRINT
+
+ifeq ($(build_droidsans_fallback),true)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := DroidSansFallback.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_SRC_FILES := $(droidsans_fallback_src)
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
 include $(BUILD_PREBUILT)
 droidsans_fallback_src :=
 
-endif  # SMALLER_FONT_FOOTPRINT
+endif  # build_droidsans_fallback
+
+build_droidsans_fallback :=
 
 ################################
 # Build the rest of font files as prebuilt.
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 3ebd57b..1e39bfa 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -124,9 +124,15 @@
 }
 
 void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) {
-    interruptForFunctorInvoke();
-    (*functor)(mode, info);
-    resumeFromFunctorInvoke();
+    if (mode == DrawGlInfo::kModeProcessNoContext) {
+        // If there's no context we don't need to interrupt as there's
+        // no gl state to save/restore
+        (*functor)(mode, info);
+    } else {
+        interruptForFunctorInvoke();
+        (*functor)(mode, info);
+        resumeFromFunctorInvoke();
+    }
 }
 
 void RenderState::interruptForFunctorInvoke() {
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index acdadd7..e99a37a 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -604,6 +604,10 @@
     public static final int SYNC_EVENT_NONE = 0;
     public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1;
 
+    /**
+     * @return command completion status, one of {@link #AUDIO_STATUS_OK},
+     *     {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED}
+     */
     public static native int setDeviceConnectionState(int device, int state,
                                                       String device_address, String device_name);
     public static native int getDeviceConnectionState(int device, String device_address);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6a22f22..0802d30 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4024,6 +4024,16 @@
         }
         if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) {
             final int oldScore = nai.getCurrentScore();
+            if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) !=
+                    networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
+                try {
+                    mNetd.setNetworkPermission(nai.network.netId,
+                            networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ?
+                                    null : NetworkManagementService.PERMISSION_SYSTEM);
+                } catch (RemoteException e) {
+                    loge("Exception in setNetworkPermission: " + e);
+                }
+            }
             synchronized (nai) {
                 nai.networkCapabilities = networkCapabilities;
             }
@@ -4491,7 +4501,10 @@
                             (networkAgent.networkMisc == null ||
                                 !networkAgent.networkMisc.allowBypass));
                 } else {
-                    mNetd.createPhysicalNetwork(networkAgent.network.netId);
+                    mNetd.createPhysicalNetwork(networkAgent.network.netId,
+                            networkAgent.networkCapabilities.hasCapability(
+                                    NET_CAPABILITY_NOT_RESTRICTED) ?
+                                    null : NetworkManagementService.PERMISSION_SYSTEM);
                 }
             } catch (Exception e) {
                 loge("Error creating network " + networkAgent.network.netId + ": "
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0e3134d..433f707 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -131,6 +131,19 @@
      */
     public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
 
+    /**
+     * String to pass to netd to indicate that a network is only accessible
+     * to apps that have the CHANGE_NETWORK_STATE permission.
+     */
+    public static final String PERMISSION_NETWORK = "NETWORK";
+
+    /**
+     * String to pass to netd to indicate that a network is only
+     * accessible to system apps and those with the CONNECTIVITY_INTERNAL
+     * permission.
+     */
+    public static final String PERMISSION_SYSTEM = "SYSTEM";
+
     class NetdResponseCode {
         /* Keep in sync with system/netd/server/ResponseCode.h */
         public static final int InterfaceListResult       = 110;
@@ -2329,11 +2342,15 @@
     }
 
     @Override
-    public void createPhysicalNetwork(int netId) {
+    public void createPhysicalNetwork(int netId, String permission) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "create", netId);
+            if (permission != null) {
+                mConnector.execute("network", "create", netId, permission);
+            } else {
+                mConnector.execute("network", "create", netId);
+            }
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -2425,6 +2442,22 @@
     }
 
     @Override
+    public void setNetworkPermission(int netId, String permission) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+        try {
+            if (permission != null) {
+                mConnector.execute("network", "permission", "network", "set", permission, netId);
+            } else {
+                mConnector.execute("network", "permission", "network", "clear", netId);
+            }
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+
+    @Override
     public void setPermission(String permission, int[] uids) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 32fd56a..83e8db0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -527,14 +527,14 @@
                     + ", pid " + Binder.getCallingPid());
         }
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot get secrets for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -627,14 +627,14 @@
         }
         if (account == null) throw new IllegalArgumentException("account is null");
         if (key == null) throw new IllegalArgumentException("key is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot get user data for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -664,22 +664,32 @@
 
         final long identityToken = clearCallingIdentity();
         try {
-            Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
-                    authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
-            AuthenticatorDescription[] types =
-                    new AuthenticatorDescription[authenticatorCollection.size()];
-            int i = 0;
-            for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
-                    : authenticatorCollection) {
-                types[i] = authenticator.type;
-                i++;
-            }
-            return types;
+            return getAuthenticatorTypesInternal(userId);
+
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    /**
+     * Should only be called inside of a clearCallingIdentity block.
+     */
+    private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId) {
+        Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
+                authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
+        AuthenticatorDescription[] types =
+                new AuthenticatorDescription[authenticatorCollection.size()];
+        int i = 0;
+        for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
+                : authenticatorCollection) {
+            types[i] = authenticator.type;
+            i++;
+        }
+        return types;
+    }
+
+
+
     private boolean isCrossUser(int callingUid, int userId) {
         return (userId != UserHandle.getCallingUserId()
                 && callingUid != Process.myUid()
@@ -697,7 +707,8 @@
                     + ", pid " + Binder.getCallingPid());
         }
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot explicitly add accounts of type: %s",
                     callingUid,
@@ -713,12 +724,10 @@
          */
 
         // fails if the account already exists
-        int uid = getCallingUid();
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
-            return addAccountInternal(accounts, account, password, extras, false, uid);
+            return addAccountInternal(accounts, account, password, extras, false, callingUid);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -794,25 +803,26 @@
         if (account == null) {
             throw new IllegalArgumentException("account is null");
         }
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot notify authentication for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = Binder.getCallingUserHandle().getIdentifier();
+
         if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
             return false;
         }
-        int user = UserHandle.getCallingUserId();
+
         long identityToken = clearCallingIdentity();
         try {
-            UserAccounts accounts = getUserAccounts(user);
+            UserAccounts accounts = getUserAccounts(userId);
+            return updateLastAuthenticatedTime(account);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return updateLastAuthenticatedTime(account);
     }
 
     private boolean updateLastAuthenticatedTime(Account account) {
@@ -985,8 +995,9 @@
         if (response == null) throw new IllegalArgumentException("response is null");
         if (account == null) throw new IllegalArgumentException("account is null");
         if (features == null) throw new IllegalArgumentException("features is null");
-        checkReadAccountsPermitted(callingUid, account.type);
         int userId = UserHandle.getCallingUserId();
+        checkReadAccountsPermitted(callingUid, account.type, userId);
+
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1062,14 +1073,14 @@
                 + ", pid " + Binder.getCallingPid());
         }
         if (accountToRename == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(accountToRename.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(accountToRename.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot rename accounts of type: %s",
                     callingUid,
                     accountToRename.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1211,14 +1222,15 @@
          * authenticator.  This will let users remove accounts (via Settings in the system) but not
          * arbitrary applications (like competing authenticators).
          */
-        if (!isAccountManagedByCaller(account.type, callingUid) && !isSystemUid(callingUid)) {
+        UserHandle user = new UserHandle(userId);
+        if (!isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())
+                && !isSystemUid(callingUid)) {
             String msg = String.format(
                     "uid %s cannot remove accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-
         if (!canUserModifyAccounts(userId)) {
             try {
                 response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED,
@@ -1235,10 +1247,7 @@
             }
             return;
         }
-
-        UserHandle user = new UserHandle(userId);
         long identityToken = clearCallingIdentity();
-
         UserAccounts accounts = getUserAccounts(userId);
         cancelNotification(getSigninRequiredNotificationId(accounts, account), user);
         synchronized(accounts.credentialsPermissionNotificationIds) {
@@ -1268,6 +1277,7 @@
                     + ", caller's uid " + callingUid
                     + ", pid " + Binder.getCallingPid());
         }
+        int userId = Binder.getCallingUserHandle().getIdentifier();
         if (account == null) {
             /*
              * Null accounts should result in returning false, as per
@@ -1275,22 +1285,18 @@
              */
             Log.e(TAG, "account is null");
             return false;
-        } else if (!isAccountManagedByCaller(account.type, callingUid)) {
+        } else if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot explicitly add accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-
         UserAccounts accounts = getUserAccountsForCaller();
-        int userId = Binder.getCallingUserHandle().getIdentifier();
         if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
             return false;
         }
-
         logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
-
         long identityToken = clearCallingIdentity();
         try {
             return removeAccountInternal(accounts, account);
@@ -1524,14 +1530,14 @@
         }
         if (account == null) throw new IllegalArgumentException("account is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot peek the authtokens associated with accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1552,14 +1558,14 @@
         }
         if (account == null) throw new IllegalArgumentException("account is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot set auth tokens associated with accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1578,14 +1584,14 @@
                     + ", pid " + Binder.getCallingPid());
         }
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot set secrets for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1642,14 +1648,14 @@
                     + ", pid " + Binder.getCallingPid());
         }
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot clear passwords for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1670,14 +1676,14 @@
         }
         if (key == null) throw new IllegalArgumentException("key is null");
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (!isAccountManagedByCaller(account.type, callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format(
                     "uid %s cannot set user data for accounts of type: %s",
                     callingUid,
                     account.type);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -1840,8 +1846,8 @@
 
         // skip the check if customTokens
         final int callerUid = Binder.getCallingUid();
-        final boolean permissionGranted = customTokens ||
-            permissionIsGranted(account, authTokenType, callerUid);
+        final boolean permissionGranted =
+                customTokens || permissionIsGranted(account, authTokenType, callerUid, userId);
 
         // Get the calling package. We will use it for the purpose of caching.
         final String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
@@ -2363,14 +2369,14 @@
         }
         if (response == null) throw new IllegalArgumentException("response is null");
         if (accountType == null) throw new IllegalArgumentException("accountType is null");
-        if (!isAccountManagedByCaller(accountType, callingUid) && !isSystemUid(callingUid)) {
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(accountType, callingUid, userId) && !isSystemUid(callingUid)) {
             String msg = String.format(
                     "uid %s cannot edit authenticator properites for account type: %s",
                     callingUid,
                     accountType);
             throw new SecurityException(msg);
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -2493,20 +2499,22 @@
     }
 
     /**
-     * Returns the accounts for a specific user
+     * Returns the accounts visible to the client within the context of a specific user
      * @hide
      */
     public Account[] getAccounts(int userId) {
         int callingUid = Binder.getCallingUid();
-        if (!isReadAccountsPermitted(callingUid, null)) {
+        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+        if (visibleAccountTypes.isEmpty()) {
             return new Account[0];
         }
         long identityToken = clearCallingIdentity();
         try {
-            UserAccounts accounts = getUserAccounts(userId);
-            synchronized (accounts.cacheLock) {
-                return getAccountsFromCacheLocked(accounts, null, callingUid, null);
-            }
+            return getAccountsInternal(
+                    userId,
+                    callingUid,
+                    null,  // packageName
+                    visibleAccountTypes);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -2588,22 +2596,52 @@
             callingUid = packageUid;
         }
 
-        // Authenticators should be able to see their own accounts regardless of permissions.
-        if (TextUtils.isEmpty(type) && !isReadAccountsPermitted(callingUid, type)) {
+        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+        if (visibleAccountTypes.isEmpty()
+                || (type != null && !visibleAccountTypes.contains(type))) {
             return new Account[0];
-        }
+        } else if (visibleAccountTypes.contains(type)) {
+            // Prune the list down to just the requested type.
+            visibleAccountTypes = new ArrayList<>();
+            visibleAccountTypes.add(type);
+        } // else aggregate all the visible accounts (it won't matter if the list is empty).
 
         long identityToken = clearCallingIdentity();
         try {
-            UserAccounts accounts = getUserAccounts(userId);
-            synchronized (accounts.cacheLock) {
-                return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage);
-            }
+            return getAccountsInternal(
+                    userId,
+                    callingUid,
+                    callingPackage,
+                    visibleAccountTypes);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    private Account[] getAccountsInternal(
+            int userId,
+            int callingUid,
+            String callingPackage,
+            List<String> visibleAccountTypes) {
+        UserAccounts accounts = getUserAccounts(userId);
+        synchronized (accounts.cacheLock) {
+            UserAccounts userAccounts = getUserAccounts(userId);
+            ArrayList<Account> visibleAccounts = new ArrayList<>();
+            for (String visibleType : visibleAccountTypes) {
+                Account[] accountsForType = getAccountsFromCacheLocked(
+                        userAccounts, visibleType, callingUid, callingPackage);
+                if (accountsForType != null) {
+                    visibleAccounts.addAll(Arrays.asList(accountsForType));
+                }
+            }
+            Account[] result = new Account[visibleAccounts.size()];
+            for (int i = 0; i < visibleAccounts.size(); i++) {
+                result[i] = visibleAccounts.get(i);
+            }
+            return result;
+        }
+    }
+
     @Override
     public boolean addSharedAccountAsUser(Account account, int userId) {
         userId = handleIncomingUser(userId);
@@ -2739,8 +2777,12 @@
         }
         if (response == null) throw new IllegalArgumentException("response is null");
         if (type == null) throw new IllegalArgumentException("accountType is null");
-        if (!isReadAccountsPermitted(callingUid, type)) {
+        int userId = UserHandle.getCallingUserId();
+
+        List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+        if (!visibleAccountTypes.contains(type)) {
             Bundle result = new Bundle();
+            // Need to return just the accounts that are from matching signatures.
             result.putParcelableArray(AccountManager.KEY_ACCOUNTS, new Account[0]);
             try {
                 response.onResult(result);
@@ -2749,7 +2791,6 @@
             }
             return;
         }
-        int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts userAccounts = getUserAccounts(userId);
@@ -2763,7 +2804,11 @@
                 onResult(response, result);
                 return;
             }
-            new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features,
+            new GetAccountsByTypeAndFeatureSession(
+                    userAccounts,
+                    response,
+                    type,
+                    features,
                     callingUid).bind();
         } finally {
             restoreCallingIdentity(identityToken);
@@ -3696,10 +3741,11 @@
         return false;
     }
 
-    private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
+    private boolean permissionIsGranted(
+            Account account, String authTokenType, int callerUid, int userId) {
         final boolean isPrivileged = isPrivileged(callerUid);
         final boolean fromAuthenticator = account != null
-                && isAccountManagedByCaller(account.type, callerUid);
+                && isAccountManagedByCaller(account.type, callerUid, userId);
         final boolean hasExplicitGrants = account != null
                 && hasExplicitlyGrantedPermission(account, authTokenType, callerUid);
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -3711,23 +3757,45 @@
         return fromAuthenticator || hasExplicitGrants || isPrivileged;
     }
 
-    private boolean isAccountManagedByCaller(String accountType, int callingUid) {
+    private boolean isAccountVisibleToCaller(String accountType, int callingUid, int userId) {
         if (accountType == null) {
             return false;
+        } else {
+            return getTypesVisibleToCaller(callingUid, userId).contains(accountType);
         }
-        final int callingUserId = UserHandle.getUserId(callingUid);
+    }
+
+    private boolean isAccountManagedByCaller(String accountType, int callingUid, int userId) {
+        if (accountType == null) {
+            return false;
+        } else {
+            return getTypesManagedByCaller(callingUid, userId).contains(accountType);
+        }
+    }
+
+    private List<String> getTypesVisibleToCaller(int callingUid, int userId) {
+        boolean isPermitted =
+                isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS,
+                        Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
+        Log.i(TAG, String.format("getTypesVisibleToCaller: isPermitted? %s", isPermitted));
+        return getTypesForCaller(callingUid, userId, isPermitted);
+    }
+
+    private List<String> getTypesManagedByCaller(int callingUid, int userId) {
+        return getTypesForCaller(callingUid, userId, false);
+    }
+
+    private List<String> getTypesForCaller(
+            int callingUid, int userId, boolean isOtherwisePermitted) {
+        List<String> managedAccountTypes = new ArrayList<>();
         for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
-                mAuthenticatorCache.getAllServices(callingUserId)) {
-            if (serviceInfo.type.type.equals(accountType)) {
-                /*
-                 * We can't simply compare uids because uids can be recycled before the
-                 * authenticator cache is updated.
-                 */
-                final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
-                return sigChk == PackageManager.SIGNATURE_MATCH;
+                mAuthenticatorCache.getAllServices(userId)) {
+            final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
+            if (isOtherwisePermitted || sigChk == PackageManager.SIGNATURE_MATCH) {
+                managedAccountTypes.add(serviceInfo.type.type);
             }
         }
-        return false;
+        return managedAccountTypes;
     }
 
     private boolean isAccountPresentForCaller(String accountName, String accountType) {
@@ -3792,28 +3860,12 @@
         return false;
     }
 
-    private boolean isReadAccountsPermitted(int callingUid, String accountType) {
-        /*
-         * Settings app (which is in the same uid as AcocuntManagerService), apps with the
-         * GET_ACCOUNTS permission or authenticators that own the account type should be able to
-         * access accounts of the specified account.
-         */
-        boolean isPermitted =
-                isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS,
-                        Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
-        boolean isAccountManagedByCaller = isAccountManagedByCaller(accountType, callingUid);
-        Log.w(TAG, String.format(
-                "isReadAccountPermitted: isPermitted: %s, isAM: %s",
-                isPermitted,
-                isAccountManagedByCaller));
-        return isPermitted || isAccountManagedByCaller;
-    }
-
     /** Succeeds if any of the specified permissions are granted. */
     private void checkReadAccountsPermitted(
             int callingUid,
-            String accountType) {
-        if (!isReadAccountsPermitted(callingUid, accountType)) {
+            String accountType,
+            int userId) {
+        if (!isAccountVisibleToCaller(accountType, callingUid, userId)) {
             String msg = String.format(
                     "caller uid %s cannot access %s accounts",
                     callingUid,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 094cb57..a0ededf 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4730,13 +4730,19 @@
                 Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected);
             }
             if (connect && !isConnected) {
-                AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
-                        address, deviceName);
+                final int res = AudioSystem.setDeviceConnectionState(device,
+                        AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName);
+                if (res != AudioSystem.AUDIO_STATUS_OK) {
+                    Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) +
+                            " due to command error " + res );
+                    return false;
+                }
                 mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address));
                 return true;
             } else if (!connect && isConnected) {
-                AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                        address, deviceName);
+                AudioSystem.setDeviceConnectionState(device,
+                        AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName);
+                // always remove even if disconnection failed
                 mConnectedDevices.remove(deviceKey);
                 return true;
             }
@@ -4869,7 +4875,10 @@
             boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
                             (((device & AudioSystem.DEVICE_BIT_IN) != 0) &&
                              ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));
-            handleDeviceConnection(state == 1, device, address, deviceName);
+            if (!handleDeviceConnection(state == 1, device, address, deviceName)) {
+                // change of connection state failed, bailout
+                return;
+            }
             if (state != 0) {
                 if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
                     (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 658f6f8..c998c2c 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -297,7 +297,6 @@
     private final UserManager mUserManager;
 
     private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds
-    private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours
 
     private List<UserInfo> getAllUsers() {
         return mUserManager.getUsers();
@@ -1478,9 +1477,9 @@
         final long now = SystemClock.elapsedRealtime();
         pw.print("now: "); pw.print(now);
         pw.println(" (" + formatTime(System.currentTimeMillis()) + ")");
-        pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000));
+        pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis / 1000));
         pw.println(" (HH:MM:SS)");
-        pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000));
+        pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now / 1000));
                 pw.println(" (HH:MM:SS)");
         pw.print("time spent syncing: ");
                 pw.print(DateUtils.formatElapsedTime(
@@ -1497,11 +1496,6 @@
             pw.println("no alarm is scheduled (there had better not be any pending syncs)");
         }
 
-        pw.print("notification info: ");
-        final StringBuilder sb = new StringBuilder();
-        mSyncHandler.mSyncNotificationInfo.toString(sb);
-        pw.println(sb.toString());
-
         pw.println();
         pw.println("Active Syncs: " + mActiveSyncContexts.size());
         final PackageManager pm = mContext.getPackageManager();
@@ -1514,8 +1508,8 @@
             pw.println();
         }
 
+        final StringBuilder sb = new StringBuilder();
         synchronized (mSyncQueue) {
-            sb.setLength(0);
             mSyncQueue.dump(sb);
             // Dump Pending Operations.
             getSyncStorageEngine().dumpPendingOperations(sb);
@@ -2349,7 +2343,6 @@
 
                 }
             } finally {
-                manageSyncNotificationLocked();
                 manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime);
                 mSyncTimeTracker.update();
                 mSyncManagerWakeLock.release();
@@ -3169,67 +3162,6 @@
             throw new IllegalStateException("we are not in an error state, " + syncResult);
         }
 
-        private void manageSyncNotificationLocked() {
-            boolean shouldCancel;
-            boolean shouldInstall;
-
-            if (mActiveSyncContexts.isEmpty()) {
-                mSyncNotificationInfo.startTime = null;
-
-                // we aren't syncing. if the notification is active then remember that we need
-                // to cancel it and then clear out the info
-                shouldCancel = mSyncNotificationInfo.isActive;
-                shouldInstall = false;
-            } else {
-                // we are syncing
-                final long now = SystemClock.elapsedRealtime();
-                if (mSyncNotificationInfo.startTime == null) {
-                    mSyncNotificationInfo.startTime = now;
-                }
-
-                // there are three cases:
-                // - the notification is up: do nothing
-                // - the notification is not up but it isn't time yet: don't install
-                // - the notification is not up and it is time: need to install
-
-                if (mSyncNotificationInfo.isActive) {
-                    shouldInstall = shouldCancel = false;
-                } else {
-                    // it isn't currently up, so there is nothing to cancel
-                    shouldCancel = false;
-
-                    final boolean timeToShowNotification =
-                            now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY;
-                    if (timeToShowNotification) {
-                        shouldInstall = true;
-                    } else {
-                        // show the notification immediately if this is a manual sync
-                        shouldInstall = false;
-                        for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) {
-                            final boolean manualSync = activeSyncContext.mSyncOperation.extras
-                                    .getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
-                            if (manualSync) {
-                                shouldInstall = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (shouldCancel && !shouldInstall) {
-                mNeedSyncActiveNotification = false;
-                sendSyncStateIntent();
-                mSyncNotificationInfo.isActive = false;
-            }
-
-            if (shouldInstall) {
-                mNeedSyncActiveNotification = true;
-                sendSyncStateIntent();
-                mSyncNotificationInfo.isActive = true;
-            }
-        }
-
         private void manageSyncAlarmLocked(long nextPeriodicEventElapsedTime,
                 long nextPendingEventElapsedTime) {
             // in each of these cases the sync loop will be kicked, which will cause this
@@ -3238,13 +3170,6 @@
             if (mStorageIsLow) return;
             if (mDeviceIsIdle) return;
 
-            // When the status bar notification should be raised
-            final long notificationTime =
-                    (!mSyncHandler.mSyncNotificationInfo.isActive
-                            && mSyncHandler.mSyncNotificationInfo.startTime != null)
-                            ? mSyncHandler.mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY
-                            : Long.MAX_VALUE;
-
             // When we should consider canceling an active sync
             long earliestTimeoutTime = Long.MAX_VALUE;
             for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
@@ -3260,24 +3185,14 @@
             }
 
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.v(TAG, "manageSyncAlarm: notificationTime is " + notificationTime);
-            }
-
-            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "manageSyncAlarm: earliestTimeoutTime is " + earliestTimeoutTime);
-            }
-
-            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "manageSyncAlarm: nextPeriodicEventElapsedTime is "
                         + nextPeriodicEventElapsedTime);
-            }
-            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "manageSyncAlarm: nextPendingEventElapsedTime is "
                         + nextPendingEventElapsedTime);
             }
 
-            long alarmTime = Math.min(notificationTime, earliestTimeoutTime);
-            alarmTime = Math.min(alarmTime, nextPeriodicEventElapsedTime);
+            long alarmTime = Math.min(earliestTimeoutTime, nextPeriodicEventElapsedTime);
             alarmTime = Math.min(alarmTime, nextPendingEventElapsedTime);
 
             // Bound the alarm time.
@@ -3288,24 +3203,16 @@
                             + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN));
                 }
                 alarmTime = now + SYNC_ALARM_TIMEOUT_MIN;
-            } else if (alarmTime > now + SYNC_ALARM_TIMEOUT_MAX) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "manageSyncAlarm: the alarmTime is too large, "
-                            + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN));
-                }
-                alarmTime = now + SYNC_ALARM_TIMEOUT_MAX;
             }
 
-            // determine if we need to set or cancel the alarm
+            // Determine if we need to set or cancel the alarm
             boolean shouldSet = false;
             boolean shouldCancel = false;
             final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime);
-            final boolean needAlarm = alarmTime != Long.MAX_VALUE;
-            if (needAlarm) {
-                // Need the alarm if
-                //  - it's currently not set
-                //  - if the alarm is set in the past.
-                if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
+
+            if (alarmTime != Long.MAX_VALUE) {
+                // Need the alarm if it isn't set or has changed.
+                if (!alarmIsActive || alarmTime != mAlarmScheduleTime) {
                     shouldSet = true;
                 }
             } else {
@@ -3329,14 +3236,6 @@
             }
         }
 
-        private void sendSyncStateIntent() {
-            Intent syncStateIntent = new Intent(Intent.ACTION_SYNC_STATE_CHANGED);
-            syncStateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            syncStateIntent.putExtra("active", mNeedSyncActiveNotification);
-            syncStateIntent.putExtra("failing", false);
-            mContext.sendBroadcastAsUser(syncStateIntent, UserHandle.OWNER);
-        }
-
         private void installHandleTooManyDeletesNotification(Account account, String authority,
                 long numDeletes, int userId) {
             if (mNotificationMgr == null) return;
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index a029b0e..3ea4f2c 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -127,9 +127,7 @@
         IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
             @Override
             public void binderDied() {
-                synchronized (mLock) {
-                    removeCallback(callback);
-                }
+                removeCallback(callback);
             }
         };
         synchronized (mLock) {
@@ -344,6 +342,7 @@
         public final String packageName;
         public final UserHandle userHandle;
 
+        private IMediaProjectionCallback mCallback;
         private IBinder mToken;
         private IBinder.DeathRecipient mDeathEater;
         private int mType;
@@ -406,7 +405,8 @@
                     throw new IllegalStateException(
                             "Cannot start already started MediaProjection");
                 }
-                registerCallback(callback);
+                mCallback = callback;
+                registerCallback(mCallback);
                 try {
                     mToken = callback.asBinder();
                     mDeathEater = new IBinder.DeathRecipient() {
@@ -435,8 +435,11 @@
                             + "pid=" + Binder.getCallingPid() + ")");
                     return;
                 }
-                mToken.unlinkToDeath(mDeathEater, 0);
                 stopProjectionLocked(this);
+                mToken.unlinkToDeath(mDeathEater, 0);
+                mToken = null;
+                unregisterCallback(mCallback);
+                mCallback = null;
             }
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7a6895f..9426b76 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1842,7 +1842,7 @@
         }
         pw.println(':');
         int N;
-        final boolean zenOnly = filter != null && filter.zen;
+        final boolean zenOnly = filter.filtered && filter.zen;
 
         if (!zenOnly) {
             synchronized (mToastQueue) {
@@ -1864,13 +1864,13 @@
                     pw.println("  Notification List:");
                     for (int i=0; i<N; i++) {
                         final NotificationRecord nr = mNotificationList.get(i);
-                        if (filter != null && !filter.matches(nr.sbn)) continue;
+                        if (filter.filtered && !filter.matches(nr.sbn)) continue;
                         nr.dump(pw, "    ", getContext(), filter.redact);
                     }
                     pw.println("  ");
                 }
 
-                if (filter == null) {
+                if (!filter.filtered) {
                     N = mLights.size();
                     if (N > 0) {
                         pw.println("  Lights List:");
@@ -1911,7 +1911,7 @@
                 mUsageStats.dump(pw, "    ", filter);
             }
 
-            if (filter == null || zenOnly) {
+            if (!filter.filtered || zenOnly) {
                 pw.println("\n  Zen Mode:");
                 pw.print("    mInterruptionFilter="); pw.println(mInterruptionFilter);
                 mZenModeHelper.dump(pw, "    ");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6fe8b8a..11e30b5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15814,16 +15814,27 @@
                         "Cannot move system application");
             }
 
-            if (Objects.equals(ps.volumeUuid, volumeUuid)) {
-                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
-                        "Package already moved to " + volumeUuid);
+            if (pkg.applicationInfo.isExternalAsec()) {
+                currentAsec = true;
+                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
+            } else if (pkg.applicationInfo.isForwardLocked()) {
+                currentAsec = true;
+                currentVolumeUuid = "forward_locked";
+            } else {
+                currentAsec = false;
+                currentVolumeUuid = ps.volumeUuid;
+
+                final File probe = new File(pkg.codePath);
+                final File probeOat = new File(probe, "oat");
+                if (!probe.isDirectory() || !probeOat.isDirectory()) {
+                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+                            "Move only supported for modern cluster style installs");
+                }
             }
 
-            final File probe = new File(pkg.codePath);
-            final File probeOat = new File(probe, "oat");
-            if (!probe.isDirectory() || !probeOat.isDirectory()) {
+            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
-                        "Move only supported for modern cluster style installs");
+                        "Package already moved to " + volumeUuid);
             }
 
             if (ps.frozen) {
@@ -15832,9 +15843,6 @@
             }
             ps.frozen = true;
 
-            currentAsec = pkg.applicationInfo.isForwardLocked()
-                    || pkg.applicationInfo.isExternalAsec();
-            currentVolumeUuid = ps.volumeUuid;
             codeFile = new File(pkg.codePath);
             installerPackageName = ps.installerPackageName;
             packageAbiOverride = ps.cpuAbiOverrideString;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 736b153..82ffa47 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -613,6 +613,7 @@
                 p.sharedUser = origPackage.sharedUser;
                 p.appId = origPackage.appId;
                 p.origPackage = origPackage;
+                p.getPermissionsState().copyFrom(origPackage.getPermissionsState());
                 mRenamedPackages.put(name, origPackage.name);
                 name = origPackage.name;
                 // Update new package state.
@@ -812,6 +813,20 @@
             p.sharedUser = sharedUser;
             p.appId = sharedUser.userId;
         }
+
+        // If the we know about this user id, we have to update it as it
+        // has to point to the same PackageSetting instance as the package.
+        Object userIdPs = getUserIdLPr(p.appId);
+        if (sharedUser == null) {
+            if (userIdPs != null && userIdPs != p) {
+                replaceUserIdLPw(p.appId, p);
+            }
+        } else {
+            if (userIdPs != null && userIdPs != sharedUser) {
+                replaceUserIdLPw(p.appId, sharedUser);
+            }
+        }
+
         IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name);
         if (ivi != null) {
             if (DEBUG_DOMAIN_VERIFICATION) {
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 19d29f3..696f106 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -937,6 +937,19 @@
     }
 
     private void tryNetworkFactoryRequests(int capability) throws Exception {
+        // Verify NOT_RESTRICTED is set appropriately
+        final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
+                .build().networkCapabilities;
+        if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
+                capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
+                capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
+                capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP ||
+                capability == NET_CAPABILITY_TRUSTED || capability == NET_CAPABILITY_NOT_VPN) {
+            assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+        } else {
+            assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+        }
+
         NetworkCapabilities filter = new NetworkCapabilities();
         filter.addCapability(capability);
         final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1787b91..09e15a8 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -49,10 +49,8 @@
 import com.android.server.FgThread;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -316,6 +314,9 @@
                 // Restore default functions.
                 mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
                         UsbManager.USB_FUNCTION_NONE);
+                if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) {
+                    mCurrentFunctions = UsbManager.USB_FUNCTION_MTP;
+                }
                 mCurrentFunctionsApplied = mCurrentFunctions.equals(
                         SystemProperties.get(USB_STATE_PROPERTY));
                 mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
@@ -400,6 +401,14 @@
             return waitForState(config);
         }
 
+        private void setUsbDataUnlocked(boolean enable) {
+            if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable);
+            mUsbDataUnlocked = enable;
+            updateUsbNotification();
+            updateUsbStateBroadcast();
+            setEnabledFunctions(mCurrentFunctions, true);
+        }
+
         private void setAdbEnabled(boolean enable) {
             if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
             if (enable != mAdbEnabled) {
@@ -471,7 +480,6 @@
             }
             functions = applyAdbFunction(functions);
             functions = applyOemOverrideFunction(functions);
-            functions = applyUserRestrictions(functions);
 
             if (!mCurrentFunctions.equals(functions) || !mCurrentFunctionsApplied
                     || forceRestart) {
@@ -502,13 +510,9 @@
             return functions;
         }
 
-        private String applyUserRestrictions(String functions) {
+        private boolean isUsbTransferAllowed() {
             UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-            if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
-                functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_MTP);
-                functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_PTP);
-            }
-           return functions;
+            return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
         }
 
         private void updateCurrentAccessory() {
@@ -555,7 +559,7 @@
                     | Intent.FLAG_RECEIVER_FOREGROUND);
             intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
             intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
-            intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked);
+            intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);
 
             if (mCurrentFunctions != null) {
                 String[] functions = mCurrentFunctions.split(",");
@@ -659,10 +663,7 @@
                     setEnabledFunctions(mCurrentFunctions, false);
                     break;
                 case MSG_SET_USB_DATA_UNLOCKED:
-                    mUsbDataUnlocked = (msg.arg1 == 1);
-                    updateUsbNotification();
-                    updateUsbStateBroadcast();
-                    setEnabledFunctions(mCurrentFunctions, true);
+                    setUsbDataUnlocked(msg.arg1 == 1);
                     break;
                 case MSG_SYSTEM_READY:
                     updateUsbNotification();
@@ -807,8 +808,12 @@
         }
 
         private String getDefaultFunctions() {
-            return SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
-                    UsbManager.USB_FUNCTION_ADB);
+            String func = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
+                    UsbManager.USB_FUNCTION_NONE);
+            if (UsbManager.USB_FUNCTION_NONE.equals(func)) {
+                func = UsbManager.USB_FUNCTION_MTP;
+            }
+            return func;
         }
 
         public void dump(IndentingPrintWriter pw) {
@@ -817,6 +822,7 @@
             pw.println("  mCurrentFunctionsApplied: " + mCurrentFunctionsApplied);
             pw.println("  mConnected: " + mConnected);
             pw.println("  mConfigured: " + mConfigured);
+            pw.println("  mUsbDataUnlocked: " + mUsbDataUnlocked);
             pw.println("  mCurrentAccessory: " + mCurrentAccessory);
             try {
                 pw.println("  Kernel state: "
@@ -864,11 +870,6 @@
         mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked);
     }
 
-    public boolean isUsbDataUnlocked() {
-        if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked);
-        return mHandler.mUsbDataUnlocked;
-    }
-
     private void readOemUsbOverrideConfig() {
         String[] configList = mContext.getResources().getStringArray(
             com.android.internal.R.array.config_oemUsbModeOverride);
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index f93a2ef..edd9201 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -322,23 +322,10 @@
     @Override
     public void setUsbDataUnlocked(boolean unlocked) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
-        // If attempt to change USB function while file transfer is restricted, ensure that
-        // usb data is always locked, and return.
-        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
-            if (mDeviceManager != null) mDeviceManager.setUsbDataUnlocked(false);
-            return;
-        }
         mDeviceManager.setUsbDataUnlocked(unlocked);
     }
 
     @Override
-    public boolean isUsbDataUnlocked() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
-        return mDeviceManager.isUsbDataUnlocked();
-    }
-
-    @Override
     public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
         mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0bb04f8..2415165 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2060,6 +2060,8 @@
      * <p>
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *   OR
+     *   {@link android.Manifest.permission#READ_SMS}
      * <p>
      * The default SMS app can also use this.
      */
@@ -2073,6 +2075,8 @@
      * <p>
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *   OR
+     *   {@link android.Manifest.permission#READ_SMS}
      * <p>
      * The default SMS app can also use this.
      *
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index cc1e976..8a20012 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -363,11 +363,10 @@
     }
 
     /** {@hide} */
-    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
+    public ScanResult(String Ssid, String BSSID, String caps, int level, int frequency,
             long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
             boolean is80211McRTTResponder) {
-        this.wifiSsid = wifiSsid;
-        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
+        this.SSID = Ssid;
         this.BSSID = BSSID;
         this.capabilities = caps;
         this.level = level;
@@ -385,6 +384,15 @@
         }
     }
 
+    /** {@hide} */
+    public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, String caps, int level,
+                  int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
+                  int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) {
+        this(Ssid, BSSID, caps,level, frequency, tsf, distCm, distSdCm, channelWidth, centerFreq0,
+                centerFreq1, is80211McRTTResponder);
+        this.wifiSsid = wifiSsid;
+    }
+
     /** copy constructor {@hide} */
     public ScanResult(ScanResult source) {
         if (source != null) {
@@ -469,6 +477,7 @@
         } else {
             dest.writeInt(0);
         }
+        dest.writeString(SSID);
         dest.writeString(BSSID);
         dest.writeString(capabilities);
         dest.writeInt(level);
@@ -512,6 +521,7 @@
                 }
                 ScanResult sr = new ScanResult(
                     wifiSsid,
+                    in.readString(),                    /* SSID  */
                     in.readString(),                    /* BSSID */
                     in.readString(),                    /* capabilities */
                     in.readInt(),                       /* level */
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index a3dc077..a65f250 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -255,9 +255,7 @@
             mResults = new ScanResult[s.mResults.length];
             for (int i = 0; i < s.mResults.length; i++) {
                 ScanResult result = s.mResults[i];
-                WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(result.SSID);
                 ScanResult newResult = new ScanResult(result);
-                newResult.wifiSsid = wifiSsid;
                 mResults[i] = newResult;
             }
         }