Merge "Add key for carrier_volte_provisioned"
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/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/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/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/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/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index d6e74cf..dcdda86 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -463,9 +463,28 @@
      */
     public static SubmitPdu getSubmitPdu(String scAddress,
             String destinationAddress, String message, boolean statusReportRequested) {
-        SubmitPduBase spb;
+        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
+                SubscriptionManager.getDefaultSmsSubscriptionId());
+    }
 
-        if (useCdmaFormatForMoSms()) {
+    /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message.
+     * This method will not attempt to use any GSM national language 7 bit encodings.
+     *
+     * @param scAddress Service Centre address.  Null means use default.
+     * @param destinationAddress the address of the destination for the message.
+     * @param message String representation of the message payload.
+     * @param statusReportRequested Indicates whether a report is requested for this message.
+     * @param subId Subscription of the message
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     * @hide
+     */
+    public static SubmitPdu getSubmitPdu(String scAddress,
+            String destinationAddress, String message, boolean statusReportRequested, int subId) {
+        SubmitPduBase spb;
+        if (useCdmaFormatForMoSms(subId)) {
             spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
                     destinationAddress, message, statusReportRequested, null);
         } else {
@@ -758,12 +777,27 @@
      * @return true if Cdma format should be used for MO SMS, false otherwise.
      */
     private static boolean useCdmaFormatForMoSms() {
-        if (!SmsManager.getDefault().isImsSmsSupported()) {
+        // IMS is registered with SMS support, check the SMS format supported
+        return useCdmaFormatForMoSms(SubscriptionManager.getDefaultSmsSubscriptionId());
+    }
+
+    /**
+     * Determines whether or not to use CDMA format for MO SMS.
+     * If SMS over IMS is supported, then format is based on IMS SMS format,
+     * otherwise format is based on current phone type.
+     *
+     * @param subId Subscription for which phone type is returned.
+     *
+     * @return true if Cdma format should be used for MO SMS, false otherwise.
+     */
+    private static boolean useCdmaFormatForMoSms(int subId) {
+        SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
+        if (!smsManager.isImsSmsSupported()) {
             // use Voice technology to determine SMS format.
-            return isCdmaVoice();
+            return isCdmaVoice(subId);
         }
         // IMS is registered with SMS support, check the SMS format supported
-        return (SmsConstants.FORMAT_3GPP2.equals(SmsManager.getDefault().getImsSmsFormat()));
+        return (SmsConstants.FORMAT_3GPP2.equals(smsManager.getImsSmsFormat()));
     }
 
     /**
@@ -772,10 +806,18 @@
      * @return true if current phone type is cdma, false otherwise.
      */
     private static boolean isCdmaVoice() {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        return (PHONE_TYPE_CDMA == activePhone);
+        return isCdmaVoice(SubscriptionManager.getDefaultSmsSubscriptionId());
     }
 
+     /**
+      * Determines whether or not to current phone type is cdma
+      *
+      * @return true if current phone type is cdma, false otherwise.
+      */
+     private static boolean isCdmaVoice(int subId) {
+         int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(subId);
+         return (PHONE_TYPE_CDMA == activePhone);
+   }
     /**
      * Decide if the carrier supports long SMS.
      * {@hide}
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);
         }