Merge "Telephony: Fix the failure of copying SMS to SIM card for sub2"
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index 252e3d2..fccdf14 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -96,6 +96,12 @@
     public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
         "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
 
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_IDLE_TIME_CHANGED =
+        "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
 
     /**
      * Return codes for the connect and disconnect Bluez / Dbus calls.
@@ -199,6 +205,11 @@
      */
     public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
 
+    /**
+     * @hide
+     */
+    public static final String EXTRA_IDLE_TIME = "android.bluetooth.BluetoothInputDevice.extra.IDLE_TIME";
+
     private Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
@@ -658,6 +669,56 @@
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
+
+    /**
+     * Send Get_Idle_Time command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean getIdleTime(BluetoothDevice device) {
+        if (DBG) log("getIdletime(" + device + ")");
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.getIdleTime(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Set_Idle_Time command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param idleTime Idle time to be set on HID Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
+        if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.setIdleTime(device, idleTime);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
     private static void log(String msg) {
       Log.d(TAG, msg);
     }
diff --git a/core/java/android/bluetooth/IBluetoothInputDevice.aidl b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
index 1ebb9ca..5bd3f78 100644
--- a/core/java/android/bluetooth/IBluetoothInputDevice.aidl
+++ b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
@@ -56,4 +56,12 @@
     * @hide
     */
     boolean sendData(in BluetoothDevice device, String report);
+    /**
+    * @hide
+    */
+    boolean getIdleTime(in BluetoothDevice device);
+    /**
+    * @hide
+    */
+    boolean setIdleTime(in BluetoothDevice device, byte idleTime);
 }
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
index 8891d2e..cf8f08f 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -26,8 +26,8 @@
  */
 public final class PeriodicAdvertisingParameters implements Parcelable {
 
-    private static final int INTERVAL_MAX = 80;
-    private static final int INTERVAL_MIN = 65519;
+    private static final int INTERVAL_MIN = 80;
+    private static final int INTERVAL_MAX = 65519;
 
     private final boolean includeTxPower;
     private final int interval;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index efa1959..6320134 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -39,6 +39,7 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.util.ArrayMap;
@@ -2701,6 +2702,28 @@
         }
     }
 
+    /**
+     * Constant error codes used by ConnectivityService to communicate about failures and errors
+     * across a Binder boundary.
+     * @hide
+     */
+    public interface Errors {
+        static int TOO_MANY_REQUESTS = 1;
+    }
+
+    /** @hide */
+    public static class TooManyRequestsException extends RuntimeException {}
+
+    private static RuntimeException convertServiceException(ServiceSpecificException e) {
+        switch (e.errorCode) {
+            case Errors.TOO_MANY_REQUESTS:
+                return new TooManyRequestsException();
+            default:
+                Log.w(TAG, "Unknown service error code " + e.errorCode);
+                return new RuntimeException(e);
+        }
+    }
+
     private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
     /** @hide */
     public static final int CALLBACK_PRECHECK            = BASE + 1;
@@ -2892,6 +2915,8 @@
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
+        } catch (ServiceSpecificException e) {
+            throw convertServiceException(e);
         }
         return request;
     }
@@ -3177,6 +3202,8 @@
             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
+        } catch (ServiceSpecificException e) {
+            throw convertServiceException(e);
         }
     }
 
@@ -3279,6 +3306,8 @@
             mService.pendingListenForNetwork(request.networkCapabilities, operation);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
+        } catch (ServiceSpecificException e) {
+            throw convertServiceException(e);
         }
     }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 35a3c0c..2c1796370 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9114,7 +9114,8 @@
             CALL_AUTO_RETRY,
             DOCK_AUDIO_MEDIA_ENABLED,
             ENCODED_SURROUND_OUTPUT,
-            LOW_POWER_MODE_TRIGGER_LEVEL
+            LOW_POWER_MODE_TRIGGER_LEVEL,
+            BLUETOOTH_ON
         };
 
         // Populated lazily, guarded by class object:
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 2fb3532..3d3e148 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -192,46 +192,43 @@
             NetworkStats lastStats) throws IOException {
         final NetworkStats stats =
               readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats);
-        NetworkStats.Entry entry = null; // for recycling
-
+        final ArrayMap<String, String> stackedIfaces;
         synchronized (sStackedIfaces) {
-            // For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4
-            // packet on the stacked interface, and once as translated to an IPv6 packet on the
-            // base interface. For correct stats accounting on the base interface, every 464xlat
-            // packet needs to be subtracted from the root UID on the base interface both for tx
-            // and rx traffic (http://b/12249687, http:/b/33681750).
-            final int size = sStackedIfaces.size();
-            for (int i = 0; i < size; i++) {
-                final String stackedIface = sStackedIfaces.keyAt(i);
-                final String baseIface = sStackedIfaces.valueAt(i);
-                if (!stackedIface.startsWith(CLATD_INTERFACE_PREFIX)) {
-                    continue;
-                }
-
-                NetworkStats.Entry adjust =
-                    new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, 0L, 0L);
-                for (int j = 0; j < stats.size(); j++) {
-                    entry = stats.getValues(j, entry);
-                    if (Objects.equals(entry.iface, stackedIface)) {
-                        adjust.rxBytes -= (entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA);
-                        adjust.txBytes -= (entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA);
-                        adjust.rxPackets -= entry.rxPackets;
-                        adjust.txPackets -= entry.txPackets;
-                    }
-                }
-                stats.combineValues(adjust);
-            }
+            stackedIfaces = new ArrayMap<>(sStackedIfaces);
         }
+        // Total 464xlat traffic to subtract from uid 0 on all base interfaces.
+        final NetworkStats adjustments = new NetworkStats(0, stackedIfaces.size());
 
-        // For 464xlat traffic, xt_qtaguid only counts the bytes of the inner IPv4 packet sent on
-        // the stacked interface with prefix "v4-" and drops the IPv6 header size after unwrapping.
-        // To account correctly for on-the-wire traffic, add the 20 additional bytes difference
-        // for all packets (http://b/12249687, http:/b/33681750).
+        NetworkStats.Entry entry = null; // For recycling
+
+        // For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4
+        // packet on the stacked interface, and once as translated to an IPv6 packet on the
+        // base interface. For correct stats accounting on the base interface, every 464xlat
+        // packet needs to be subtracted from the root UID on the base interface both for tx
+        // and rx traffic (http://b/12249687, http:/b/33681750).
         for (int i = 0; i < stats.size(); i++) {
             entry = stats.getValues(i, entry);
             if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) {
                 continue;
             }
+            final String baseIface = stackedIfaces.get(entry.iface);
+            if (baseIface == null) {
+                continue;
+            }
+
+            NetworkStats.Entry adjust =
+                    new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, 0L, 0L);
+            // Subtract any 464lat traffic seen for the root UID on the current base interface.
+            adjust.rxBytes -= (entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA);
+            adjust.txBytes -= (entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA);
+            adjust.rxPackets -= entry.rxPackets;
+            adjust.txPackets -= entry.txPackets;
+            adjustments.combineValues(adjust);
+
+            // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent
+            // on the stacked interface with prefix "v4-" and drops the IPv6 header size after
+            // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes
+            // difference for all packets (http://b/12249687, http:/b/33681750).
             entry.rxBytes = entry.rxPackets * IPV4V6_HEADER_DELTA;
             entry.txBytes = entry.txPackets * IPV4V6_HEADER_DELTA;
             entry.rxPackets = 0;
@@ -239,6 +236,8 @@
             stats.combineValues(entry);
         }
 
+        stats.combineAllValues(adjustments);
+
         return stats;
     }
 
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index e46f166..ae0c8a0 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -45,6 +45,7 @@
     <permission name="android.permission.BLUETOOTH_STACK" >
         <group gid="bluetooth" />
         <group gid="wakelock" />
+        <group gid="uhid" />
     </permission>
 
     <permission name="android.permission.NET_TUNNELING" >
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index 05fec5e..0835cad 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -19,7 +19,7 @@
 # Build the legacy-test library
 # =============================
 # This contains the junit.framework and android.test classes that were in
-# Android API level 25.
+# Android API level 25 excluding those from android.test.runner.
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -31,10 +31,13 @@
 
 # Build the legacy-android-test library
 # =============================
-# This contains the android.test classes that were in Android API level 25.
+# This contains the android.test classes that were in Android API level 25,
+# including those from android.test.runner.
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src/android)
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src/android) \
+    $(call all-java-files-under, ../test-runner/src/android)
 LOCAL_MODULE := legacy-android-test
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart framework junit
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index ec4c00e..61b3122 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -96,6 +96,10 @@
         WebSettings webSettings = mWebView.getSettings();
         webSettings.setJavaScriptEnabled(true);
         webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
+        webSettings.setUseWideViewPort(true);
+        webSettings.setLoadWithOverviewMode(true);
+        webSettings.setSupportZoom(true);
+        webSettings.setBuiltInZoomControls(true);
         mWebViewClient = new MyWebViewClient();
         mWebView.setWebViewClient(mWebViewClient);
         mWebView.setWebChromeClient(new MyWebChromeClient());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index bf48e5d..75ae835 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -62,11 +62,12 @@
      */
     private static final ArraySet<String> sBroadcastOnRestore;
     static {
-        sBroadcastOnRestore = new ArraySet<String>(4);
+        sBroadcastOnRestore = new ArraySet<String>(5);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_VR_LISTENERS);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_INPUT_METHODS);
+        sBroadcastOnRestore.add(Settings.Global.BLUETOOTH_ON);
     }
 
     private interface SettingsLookup {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 1262d88..5a3c7d0 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -90,6 +90,7 @@
     private static final String REASON_SYSTEM_BOOT = "system boot";
     private static final String REASON_UNEXPECTED = "unexpected crash";
     private static final String REASON_USER_SWITCH = "user switch";
+    private static final String REASON_RESTORE_USER_SETTING = "restore user setting";
 
     private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
     //Maximum msec to wait for service restart
@@ -118,6 +119,10 @@
     private static final int MESSAGE_USER_UNLOCKED = 301;
     private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
     private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
+    private static final int MESSAGE_RESTORE_USER_SETTING = 500;
+
+    private static final int RESTORE_SETTING_TO_ON = 1;
+    private static final int RESTORE_SETTING_TO_OFF = 0;
 
     private static final int MAX_SAVE_RETRIES = 3;
     private static final int MAX_ERROR_RESTART_RETRIES = 6;
@@ -315,6 +320,26 @@
                 } else {
                     if (DBG) Slog.e(TAG, "No Bluetooth Adapter address parameter found");
                 }
+            } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
+                final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
+                if (Settings.Global.BLUETOOTH_ON.equals(name)) {
+                    // The Bluetooth On state may be changed during system restore.
+                    final String prevValue = intent.getStringExtra(
+                            Intent.EXTRA_SETTING_PREVIOUS_VALUE);
+                    final String newValue = intent.getStringExtra(
+                            Intent.EXTRA_SETTING_NEW_VALUE);
+
+                    if (DBG) Slog.d(TAG, "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" +
+                                    prevValue + ", newValue=" + newValue);
+
+                    if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
+                        Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
+                                                             newValue.equals("0") ?
+                                                             RESTORE_SETTING_TO_OFF :
+                                                             RESTORE_SETTING_TO_ON, 0);
+                        mHandler.sendMessage(msg);
+                    }
+                }
             }
         }
     };
@@ -348,12 +373,14 @@
         registerForBleScanModeChange();
         mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
         mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
-        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
+        filter.addAction(Intent.ACTION_SETTING_RESTORED);
         filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         mContext.registerReceiver(mReceiver, filter);
-        filter = new IntentFilter(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
-        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-        mContext.registerReceiver(mReceiver, filter);
+
         loadStoredNameAndAddress();
         if (isBluetoothPersistedStateOn()) {
             if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
@@ -1424,6 +1451,20 @@
                     }
                     break;
 
+                case MESSAGE_RESTORE_USER_SETTING:
+                    try {
+                        if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
+                            if (DBG) Slog.d(TAG, "Restore Bluetooth state to disabled");
+                            disable(REASON_RESTORE_USER_SETTING, true);
+                        } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
+                            if (DBG) Slog.d(TAG, "Restore Bluetooth state to enabled");
+                            enable(REASON_RESTORE_USER_SETTING);
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG,"Unable to change Bluetooth On setting", e);
+                    }
+                    break;
+
                 case MESSAGE_REGISTER_ADAPTER:
                 {
                     IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 88bc54d..4f7b834 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -98,6 +98,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -4064,7 +4065,8 @@
             synchronized (mUidToNetworkRequestCount) {
                 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
                 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
-                    throw new IllegalArgumentException("Too many NetworkRequests filed");
+                    throw new ServiceSpecificException(
+                            ConnectivityManager.Errors.TOO_MANY_REQUESTS);
                 }
                 mUidToNetworkRequestCount.put(mUid, networkRequests);
             }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 42a0bad..f69fe64 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -42,22 +42,20 @@
      * **************************************************************************/
     /** Application should be visible to everyone */
     public static final int DEXOPT_PUBLIC         = 1 << 1;
-    /** Application wants to run in VM safe mode */
-    public static final int DEXOPT_SAFEMODE       = 1 << 2;
     /** Application wants to allow debugging of its code */
-    public static final int DEXOPT_DEBUGGABLE     = 1 << 3;
+    public static final int DEXOPT_DEBUGGABLE     = 1 << 2;
     /** The system boot has finished */
-    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 4;
+    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 3;
     /** Hint that the dexopt type is profile-guided. */
-    public static final int DEXOPT_PROFILE_GUIDED = 1 << 5;
+    public static final int DEXOPT_PROFILE_GUIDED = 1 << 4;
     /** The compilation is for a secondary dex file. */
-    public static final int DEXOPT_SECONDARY_DEX  = 1 << 6;
+    public static final int DEXOPT_SECONDARY_DEX  = 1 << 5;
     /** Ignore the result of dexoptNeeded and force compilation. */
-    public static final int DEXOPT_FORCE          = 1 << 7;
+    public static final int DEXOPT_FORCE          = 1 << 6;
     /** Indicates that the dex file passed to dexopt in on CE storage. */
-    public static final int DEXOPT_STORAGE_CE     = 1 << 8;
+    public static final int DEXOPT_STORAGE_CE     = 1 << 7;
     /** Indicates that the dex file passed to dexopt in on DE storage. */
-    public static final int DEXOPT_STORAGE_DE     = 1 << 9;
+    public static final int DEXOPT_STORAGE_DE     = 1 << 8;
 
     // NOTE: keep in sync with installd
     public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index ddb3639..126ad26 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -44,7 +44,6 @@
 import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
 import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
-import static com.android.server.pm.Installer.DEXOPT_SAFEMODE;
 import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX;
 import static com.android.server.pm.Installer.DEXOPT_FORCE;
 import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
@@ -381,7 +380,6 @@
 
     private int getDexFlags(ApplicationInfo info, String compilerFilter) {
         int flags = info.flags;
-        boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
         boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
         // Profile guide compiled oat files should not be public.
         boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter);
@@ -389,7 +387,6 @@
         int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
         int dexFlags =
                 (isPublic ? DEXOPT_PUBLIC : 0)
-                | (vmSafeMode ? DEXOPT_SAFEMODE : 0)
                 | (debuggable ? DEXOPT_DEBUGGABLE : 0)
                 | profileFlag
                 | DEXOPT_BOOTCOMPLETE;
@@ -508,9 +505,6 @@
         if ((flags & DEXOPT_PUBLIC) == DEXOPT_PUBLIC) {
             flagsList.add("public");
         }
-        if ((flags & DEXOPT_SAFEMODE) == DEXOPT_SAFEMODE) {
-            flagsList.add("safemode");
-        }
         if ((flags & DEXOPT_SECONDARY_DEX) == DEXOPT_SECONDARY_DEX) {
             flagsList.add("secondary");
         }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b9d22e8..24cd3c7 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -682,7 +682,7 @@
             }
 
             // send broadcast intent only if the USB state has changed
-            if (!isUsbStateChanged(intent)) {
+            if (!isUsbStateChanged(intent) && !configChanged) {
                 if (DEBUG) {
                     Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
                 }
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index f1f683c..511ac38 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -105,10 +105,11 @@
         }
 
         @Override
-        public void removeImsFeature(int slotId, int feature) throws RemoteException {
+        public void removeImsFeature(int slotId, int feature,  IImsFeatureStatusCallback c)
+                throws RemoteException {
             synchronized (mFeatures) {
                 enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature");
-                onRemoveImsFeatureInternal(slotId, feature);
+                onRemoveImsFeatureInternal(slotId, feature, c);
             }
         }
 
@@ -355,7 +356,7 @@
         if (f != null) {
             f.setContext(this);
             f.setSlotId(slotId);
-            f.setImsFeatureStatusCallback(c);
+            f.addImsFeatureStatusCallback(c);
             featureMap.put(featureType, f);
         }
 
@@ -368,7 +369,8 @@
      * defined in {@link ImsFeature}.
      */
     // Be sure to lock on mFeatures before accessing this method
-    private void onRemoveImsFeatureInternal(int slotId, int featureType) {
+    private void onRemoveImsFeatureInternal(int slotId, int featureType,
+            IImsFeatureStatusCallback c) {
         SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
         if (featureMap == null) {
             return;
@@ -379,7 +381,7 @@
             featureMap.remove(featureType);
             featureToRemove.notifyFeatureRemoved(slotId);
             // Remove reference to Binder
-            featureToRemove.setImsFeatureStatusCallback(null);
+            featureToRemove.removeImsFeatureStatusCallback(c);
         }
     }
 
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 395f1cc..9d880b7 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -28,7 +28,11 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
+import java.util.WeakHashMap;
 
 /**
  * Base class for all IMS features that are supported by the framework.
@@ -88,7 +92,8 @@
     public static final int STATE_READY = 2;
 
     private List<INotifyFeatureRemoved> mRemovedListeners = new ArrayList<>();
-    private IImsFeatureStatusCallback mStatusCallback;
+    private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
+            new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
     private @ImsState int mState = STATE_NOT_AVAILABLE;
     private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
     private Context mContext;
@@ -136,11 +141,29 @@
         }
     }
 
-    // Not final for testing.
-    public void setImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
-        mStatusCallback = c;
-        // If we have just connected, send queued status.
-        notifyFeatureState(mState);
+    public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
+        if (c == null) {
+            return;
+        }
+        try {
+            // If we have just connected, send queued status.
+            c.notifyImsFeatureStatus(mState);
+            // Add the callback if the callback completes successfully without a RemoteException.
+            synchronized (mStatusCallbacks) {
+                mStatusCallbacks.add(c);
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
+        }
+    }
+
+    public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
+        if (c == null) {
+            return;
+        }
+        synchronized (mStatusCallbacks) {
+            mStatusCallbacks.remove(c);
+        }
     }
 
     /**
@@ -148,13 +171,18 @@
      * @param state
      */
     private void notifyFeatureState(@ImsState int state) {
-        if (mStatusCallback != null) {
-            try {
-                Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
-                mStatusCallback.notifyImsFeatureStatus(state);
-            } catch (RemoteException e) {
-                mStatusCallback = null;
-                Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
+        synchronized (mStatusCallbacks) {
+            for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
+                 iter.hasNext(); ) {
+                IImsFeatureStatusCallback callback = iter.next();
+                try {
+                    Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
+                    callback.notifyImsFeatureStatus(state);
+                } catch (RemoteException e) {
+                    // remove if the callback is no longer alive.
+                    iter.remove();
+                    Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
+                }
             }
         }
         sendImsServiceIntent(state);
diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java
index cd2e46c..cb621c8 100644
--- a/telephony/java/android/telephony/mbms/ServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/ServiceInfo.java
@@ -32,7 +32,7 @@
  */
 public class ServiceInfo implements Parcelable {
     // arbitrary limit on the number of locale -> name pairs we support
-    final static int MAP_LIMIT = 50;
+    final static int MAP_LIMIT = 1000;
     /**
      * User displayable names listed by language.  Unmodifiable.
      */
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
index fbc0931..ddc661d 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
@@ -54,7 +54,7 @@
      * - Streaming status will be sent via the included listener, including an initial
      *   URL-change and State-change pair.
      */
-    StreamingService startStreaming(String appName, int subId, String serviceId,
+    int startStreaming(String appName, int subId, String serviceId,
             IStreamingServiceCallback listener);
 
     /**
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index 1c8ab7c..9f0c0e9 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -43,9 +43,9 @@
     }
 
     @Override
-    public StreamingService startStreaming(String appName, int subId,
+    public int startStreaming(String appName, int subId,
             String serviceId, IStreamingServiceCallback listener) throws RemoteException {
-        return null;
+        return 0;
     }
 
     @Override
diff --git a/telephony/java/com/android/ims/internal/IImsServiceController.aidl b/telephony/java/com/android/ims/internal/IImsServiceController.aidl
index 712816f..bb06d7e 100644
--- a/telephony/java/com/android/ims/internal/IImsServiceController.aidl
+++ b/telephony/java/com/android/ims/internal/IImsServiceController.aidl
@@ -37,7 +37,7 @@
 interface IImsServiceController {
     // ImsService Control
     void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
-    void removeImsFeature(int slotId, int feature);
+    void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c);
     // MMTel Feature
     int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent,
             in IImsRegistrationListener listener);
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index ceb0135..cc792cc 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.PendingIntent;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
 import android.content.Context;
@@ -66,8 +67,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-
-
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ConnectivityManagerTest {
@@ -296,6 +295,43 @@
         manager.requestNetwork(request, callback);
     }
 
+    @Test
+    public void testArgumentValidation() throws Exception {
+        ConnectivityManager manager = new ConnectivityManager(mCtx, mService);
+
+        NetworkRequest request = mock(NetworkRequest.class);
+        NetworkCallback callback = mock(NetworkCallback.class);
+        Handler handler = mock(Handler.class);
+        NetworkCallback nullCallback = null;
+        PendingIntent nullIntent = null;
+
+        mustFail(() -> { manager.requestNetwork(null, callback); });
+        mustFail(() -> { manager.requestNetwork(request, nullCallback); });
+        mustFail(() -> { manager.requestNetwork(request, callback, null); });
+        mustFail(() -> { manager.requestNetwork(request, callback, -1); });
+        mustFail(() -> { manager.requestNetwork(request, nullIntent); });
+
+        mustFail(() -> { manager.registerNetworkCallback(null, callback, handler); });
+        mustFail(() -> { manager.registerNetworkCallback(request, null, handler); });
+        mustFail(() -> { manager.registerNetworkCallback(request, callback, null); });
+        mustFail(() -> { manager.registerNetworkCallback(request, nullIntent); });
+
+        mustFail(() -> { manager.registerDefaultNetworkCallback(null, handler); });
+        mustFail(() -> { manager.registerDefaultNetworkCallback(callback, null); });
+
+        mustFail(() -> { manager.unregisterNetworkCallback(nullCallback); });
+        mustFail(() -> { manager.unregisterNetworkCallback(nullIntent); });
+        mustFail(() -> { manager.releaseNetworkRequest(nullIntent); });
+    }
+
+    static void mustFail(Runnable fn) {
+        try {
+            fn.run();
+            fail();
+        } catch (Exception expected) {
+        }
+    }
+
     static Message makeMessage(NetworkRequest req, int messageType) {
         Bundle bundle = new Bundle();
         bundle.putParcelable(NetworkRequest.class.getSimpleName(), req);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 5173278..3c0b8aa 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -43,6 +43,7 @@
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.ConnectivityManager.PacketKeepalive;
 import android.net.ConnectivityManager.PacketKeepaliveCallback;
+import android.net.ConnectivityManager.TooManyRequestsException;
 import android.net.INetworkPolicyManager;
 import android.net.INetworkStatsService;
 import android.net.IpPrefix;
@@ -2981,7 +2982,7 @@
                 networkCallbacks.add(networkCallback);
             }
             fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
-        } catch (IllegalArgumentException expected) {}
+        } catch (TooManyRequestsException expected) {}
         for (NetworkCallback networkCallback : networkCallbacks) {
             mCm.unregisterNetworkCallback(networkCallback);
         }
@@ -2994,7 +2995,7 @@
                 networkCallbacks.add(networkCallback);
             }
             fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
-        } catch (IllegalArgumentException expected) {}
+        } catch (TooManyRequestsException expected) {}
         for (NetworkCallback networkCallback : networkCallbacks) {
             mCm.unregisterNetworkCallback(networkCallback);
         }
@@ -3010,7 +3011,7 @@
             }
             fail("Registering " + MAX_REQUESTS +
                     " PendingIntent NetworkRequests did not throw exception");
-        } catch (IllegalArgumentException expected) {}
+        } catch (TooManyRequestsException expected) {}
         for (PendingIntent pendingIntent : pendingIntents) {
             mCm.unregisterNetworkCallback(pendingIntent);
         }
@@ -3025,7 +3026,7 @@
             }
             fail("Registering " + MAX_REQUESTS +
                     " PendingIntent NetworkCallbacks did not throw exception");
-        } catch (IllegalArgumentException expected) {}
+        } catch (TooManyRequestsException expected) {}
         for (PendingIntent pendingIntent : pendingIntents) {
             mCm.unregisterNetworkCallback(pendingIntent);
         }