Merge tag 'android-13.0.0_r32' into int/13/fp3

Android 13.0.0 release 32

* tag 'android-13.0.0_r32':
  Added API to trigger PIN/PUK commands for specific subscription.
  Make this not fail if test passed an address that doesn't exist.
  Add rahulsabnis@ as an owner
  Listen for bond state changes in bonding SL4A APIs and adds SL4A interface to reconnect over GATT
  Update oob bonding interface to use oob data's address type

Change-Id: I585f3d85cf98f1d6af19fefd9c227bff63ff85f0
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
index 4bdd943..8e54d81 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
@@ -635,27 +635,34 @@
     }
 
     /**
-     * Bond to a device using Out of Band Data.
+     * Bond to a device using Out of Band Data over LE transport.
      *
      * @param address String representation of address like "00:11:22:33:44:55"
      * @param transport String "1", "2", "3" to match TRANSPORT_*
      * @param c Hex String of the 16 octet confirmation
      * @param r Hex String of the 16 octet randomizer
+     * @param addressType type of address provided to match BluetoothDevice#ADDRESS_TYPE_*
      */
-    @Rpc(description = "Creates and Out of Band bond.")
-    public void bluetoothCreateBondOutOfBand(@RpcParameter(name = "address") String address,
-            @RpcParameter(name = "transport") String transport,
-            @RpcParameter(name = "c") String c, @RpcParameter(name = "r") String r) {
-        Log.d("bluetoothCreateBondOutOfBand(" + address + ", " + transport + "," + c + ", "
+    @Rpc(description = "Creates and Out of Band LE bond.")
+    public void bluetoothCreateLeBondOutOfBand(@RpcParameter(name = "address") String address,
+            @RpcParameter(name = "c") String c, @RpcParameter(name = "r") String r,
+            @RpcParameter(name = "addressType") @RpcDefault("1") Integer addressType) {
+        Log.d("bluetoothCreateLeBondOutOfBand(" + address + ", " + addressType + "," + c + ", "
                 + r + ")");
-        BluetoothDevice remoteDevice = mBluetoothAdapter.getRemoteDevice(address);
+        BluetoothDevice remoteDevice = mBluetoothAdapter.getRemoteLeDevice(address, addressType);
         byte[] addressBytes = new byte[7];
         int i = 0;
         for (String s : address.split(":")) {
             addressBytes[i] = hexStringToByteArray(s)[0];
             i++;
         }
-        addressBytes[i] = 0x01;
+
+        // Inserts the address type if one is provided
+        if (addressType == BluetoothDevice.ADDRESS_TYPE_PUBLIC
+                || addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
+            addressBytes[i] = addressType.byteValue();
+        }
+
         OobData p192 = null;
         OobData p256 = new OobData.LeBuilder(hexStringToByteArray(c),
                 addressBytes, OobData.LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL)
@@ -663,7 +670,7 @@
                 .build();
         mContext.registerReceiver(new BondBroadcastReceiver(),
                 new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
-        remoteDevice.createBondOutOfBand(Integer.parseInt(transport), p192, p256);
+        remoteDevice.createBondOutOfBand(BluetoothDevice.TRANSPORT_LE, p192, p256);
     }
 
     private class BondBroadcastReceiver extends BroadcastReceiver {
@@ -759,11 +766,17 @@
             @RpcParameter(name = "deviceID",
                     description = "Name or MAC address of a bluetooth device.")
                     String deviceID) throws Exception {
-        BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
-                deviceID);
-        mContext.registerReceiver(new BondBroadcastReceiver(),
-                new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
-        return mDevice.removeBond();
+        // We don't want to crash the test if the test passes an address that cannot be found.
+        try {
+            BluetoothDevice mDevice = BluetoothFacade.getDevice(
+                    mBluetoothAdapter.getBondedDevices(), deviceID);
+            mContext.registerReceiver(new BondBroadcastReceiver(),
+                    new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
+            return mDevice.removeBond();
+        } catch (Exception e) {
+            Log.d("Failed to find the device by deviceId");
+            return false;
+        }
     }
 
     @Rpc(description = "Connect to a device that is already bonded.")
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
index e60e5f1..3143c45 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
@@ -36,6 +36,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.PinResult;
 
 import com.android.internal.telephony.RILConstants;
 
@@ -1006,6 +1007,21 @@
     }
 
     /**
+     * Check if the Subscription ID is valid.
+     * @param subId the subscription ID
+     * @return    {true} if subId is valid, {false}  otherwise.
+     */
+    @Rpc(description = "Check if the Subscription ID is valid.")
+    public boolean telephonyIsSubscriptionIdValid(
+        @RpcParameter(name = "subId") Integer subId){
+        if (subId == null || !SubscriptionManager.isValidSubscriptionId(subId)) {
+            Log.e("Invalid or null subscription ID");
+            return false;
+        }
+        return true;
+    }
+
+    /**
     * Supply the puk code and pin for locked SIM.
     * @param puk the puk code string
     * @param pin the puk pin string
@@ -1019,6 +1035,25 @@
     }
 
     /**
+     * Supply the puk code and pin for locked SIM of specified subscription ID.
+     * @param subId the subscription ID
+     * @param puk the puk code string
+     * @param pin the puk pin string
+     * @return    true or false for supplying the puk code and pin successfully or unsuccessfully.
+     */
+    @Rpc(description = "Supply Puk and Pin for locked SIM " +
+        "for specified subscription ID.")
+    public boolean telephonySupplyPukForSubscription(
+        @RpcParameter(name = "subId") Integer subId,
+        @RpcParameter(name = "puk") String puk,
+        @RpcParameter(name = "pin") String pin) {
+        if (!telephonyIsSubscriptionIdValid(subId)) {
+            return false;
+        }
+        return mTelephonyManager.createForSubscriptionId(subId).supplyPuk(puk, pin);
+    }
+
+    /**
     * Supply pin for locked SIM.
     * @param pin the puk pin string
     * @return    true or false for supplying the pin successfully or unsuccessfully.
@@ -1029,6 +1064,84 @@
         return mTelephonyManager.supplyPin(pin);
     }
 
+    /**
+     * Supply pin for locked SIM of specified subscription ID.
+     * @param subId the subscription ID
+     * @param pin the puk pin string
+     * @return    true or false for supplying the pin successfully or unsuccessfully.
+     */
+    @Rpc(description = "Supply Pin for locked SIM " +
+        "for specified subscription ID.")
+    public boolean telephonySupplyPinForSubscription(
+        @RpcParameter(name = "subId") Integer subId,
+        @RpcParameter(name = "pin") String pin) {
+        if (!telephonyIsSubscriptionIdValid(subId)) {
+            return false;
+        }
+        return mTelephonyManager.createForSubscriptionId(subId).supplyPin(pin);
+    }
+
+    /**
+     * Enable or disable the ICC PIN lock of specified subscription ID.
+     * @param subId the subscription ID
+     * @param enabled "true" for enable, "false" for disable.
+     * @param pin needed to enable or disable the ICC PIN lock
+     * @return    true or false for enable/disable the pin successfully or unsuccessfully.
+     */
+    @Rpc(description = "Enable or disable the ICC PIN lock " +
+        "for specified subscription ID.")
+    public boolean telephonySetIccLockEnabledForSubscription(
+        @RpcParameter(name = "subId") Integer subId,
+        @RpcParameter(name = "enabled") Boolean enabled,
+        @RpcParameter(name = "pin") String pin) {
+        if (!telephonyIsSubscriptionIdValid(subId)) {
+            return false;
+        }
+        PinResult result= mTelephonyManager.createForSubscriptionId(subId).setIccLockEnabled(enabled,pin);
+        if(result != null) {
+            return (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS);
+        }
+        return false;
+    }
+
+    /**
+     * Check whether ICC PIN lock is enabled.
+     * @param subId the subscription ID
+     * @return   true or false for changing the ICC lock PIN successfully or unsuccessfully.
+     */
+    @Rpc(description = "Check whether ICC PIN lock is enabled " +
+        "for specified subscription ID.")
+    public boolean telephonyIsIccLockEnabled(
+        @RpcParameter(name = "subId") Integer subId) {
+        if (!telephonyIsSubscriptionIdValid(subId)) {
+            return false;
+        }
+        return mTelephonyManager.createForSubscriptionId(subId).isIccLockEnabled();
+    }
+
+    /**
+     * Change the ICC lock PIN of specified subscription ID.
+     * @param subId the subscription ID
+     * @param oldPin is the old PIN.
+     * @param newPin is the new PIN.
+     * @return    true or false for changing the ICC lock PIN successfully or unsuccessfully.
+     */
+    @Rpc(description = "Change the ICC lock PIN " +
+        "for specified subscription ID.")
+    public boolean telephonyChangeIccLockPinForSubscription(
+        @RpcParameter(name = "subId") Integer subId,
+        @RpcParameter(name = "oldPin")  String oldPin,
+        @RpcParameter(name = "newPin")  String newPin) {
+        if (!telephonyIsSubscriptionIdValid(subId)) {
+            return false;
+        }
+        PinResult result= mTelephonyManager.createForSubscriptionId(subId).changeIccLockPin(oldPin,newPin);
+        if(result != null) {
+            return (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS);
+        }
+        return false;
+    }
+
     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
             "for default subscription ID, or null if unavailable")
     public String telephonyGetSubscriberId() {
diff --git a/OWNERS b/OWNERS
index f4dea96..367c156 100644
--- a/OWNERS
+++ b/OWNERS
@@ -7,6 +7,7 @@
 jaineelm@google.com
 jpawlowski@google.com
 krisr@google.com
+rahulsabnis@google.com
 siyuanh@google.com
 tturney@google.com
 xianyuanjia@google.com