release-request-33811b80-8470-43aa-a2e6-0c80aa8b51af-for-git_oc-release-4070583 snap-temp-L92300000070865789
Change-Id: I7b28a55a6c175308adf7babfbfc57bd8b3b1261d
diff --git a/car-lib/src/android/car/ICarBluetoothUserService.aidl b/car-lib/src/android/car/ICarBluetoothUserService.aidl
index b1f7a39..a906a3c 100644
--- a/car-lib/src/android/car/ICarBluetoothUserService.aidl
+++ b/car-lib/src/android/car/ICarBluetoothUserService.aidl
@@ -24,4 +24,5 @@
void closeBluetoothConnectionProxy();
boolean isBluetoothConnectionProxyAvailable(in int profile);
void bluetoothConnectToProfile(in int profile, in BluetoothDevice device);
+ void setProfilePriority(in int profile, in BluetoothDevice device, in int priority);
}
diff --git a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
index 4cdb640..e80b843 100644
--- a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
+++ b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
@@ -24,6 +24,7 @@
import android.bluetooth.BluetoothMapClient;
import android.bluetooth.BluetoothPbapClient;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.CarSensorEvent;
import android.car.hardware.CarSensorManager;
@@ -38,6 +39,8 @@
import static android.car.settings.CarSettings.Secure.KEY_BLUETOOTH_AUTOCONNECT_PHONE_DEVICES;
import static android.car.settings.CarSettings.Secure.KEY_BLUETOOTH_AUTOCONNECT_MESSAGING_DEVICES;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
@@ -237,7 +240,7 @@
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (DBG) {
if (device != null) {
- Log.d(TAG, "Received Intent for device: " + device.getName() + action);
+ Log.d(TAG, "Received Intent for device: " + device + " " + action);
} else {
Log.d(TAG, "Received Intent no device: " + action);
}
@@ -287,6 +290,91 @@
writeDeviceInfoToSettings();
resetBluetoothDevicesConnectionInfo();
}
+ } else if (BluetoothDevice.ACTION_UUID.equals(action)) {
+ // Received during pairing with the UUIDs of the Bluetooth profiles supported by
+ // the remote device.
+ if (DBG) {
+ Log.d(TAG, "Received UUID intent for device " + device);
+ }
+ Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
+ if (uuids != null) {
+ ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length];
+ for (int i = 0; i < uuidsToSend.length; i++) {
+ uuidsToSend[i] = (ParcelUuid)uuids[i];
+ }
+ setProfilePriorities(device, uuidsToSend, BluetoothProfile.PRIORITY_ON);
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Set priority for the Bluetooth profiles.
+ *
+ * The Bluetooth service stores the priority of a Bluetooth profile per device as a key value
+ * pair - BluetoothProfile_device:<Priority>.
+ * When we pair a device from the Settings App, the expected behavior is for the app to connect
+ * on all appropriate profiles after successful pairing automatically, without the user having
+ * to explicitly issue a connect. The settings app checks for the priority of the device from
+ * the above key-value pair and if the priority is set to PRIORITY_OFF or PRIORITY_UNDEFINED,
+ * the settings app will stop with just pairing and not connect.
+ * This scenario will happen when we pair a device, then unpair it and then pair it again. When
+ * the device is unpaired, the BT stack sets the priority for that device to PRIORITY_UNDEFINED
+ * ( as a way of resetting). So, the next time the same device is paired, the Settings app will
+ * stop with just pairing and not connect as explained above. Here, we register to receive the
+ * ACTION_UUID intent, which will broadcast the UUIDs corresponding to the profiles supported by
+ * the remote device which is successfully paired and we turn on the priority so when the
+ * Settings app tries to check before connecting, the priority is set to the expected value.
+ *
+ * @param device - Remote Bluetooth device
+ * @param uuids - UUIDs of the Bluetooth Profiles supported by the remote device
+ * @param priority - priority to set
+ */
+ private void setProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids, int priority) {
+ // need the BluetoothProfile proxy to be able to call the setPriority API
+ if (mCarBluetoothUserService == null) {
+ mCarBluetoothUserService = setupBluetoothUserService();
+ }
+ if (mCarBluetoothUserService != null) {
+ for (Integer profile : mProfilesToConnect) {
+ setBluetoothProfilePriorityIfUuidFound(uuids, profile, device, priority);
+ }
+ }
+ }
+
+ private void setBluetoothProfilePriorityIfUuidFound(ParcelUuid[] uuids, int profile,
+ BluetoothDevice device, int priority) {
+ if (mCarBluetoothUserService == null || device == null) {
+ return;
+ }
+ // Build a list of UUIDs that represent a profile.
+ List<ParcelUuid> uuidsToCheck = new ArrayList<>();
+ switch (profile) {
+ case BluetoothProfile.A2DP_SINK:
+ uuidsToCheck.add(BluetoothUuid.AudioSource);
+ break;
+ case BluetoothProfile.HEADSET_CLIENT:
+ uuidsToCheck.add(BluetoothUuid.Handsfree_AG);
+ uuidsToCheck.add(BluetoothUuid.HSP_AG);
+ break;
+ case BluetoothProfile.PBAP_CLIENT:
+ uuidsToCheck.add(BluetoothUuid.PBAP_PSE);
+ break;
+ case BluetoothProfile.MAP_CLIENT:
+ uuidsToCheck.add(BluetoothUuid.MAS);
+ break;
+ }
+
+ for (ParcelUuid uuid : uuidsToCheck) {
+ if (BluetoothUuid.isUuidPresent(uuids, uuid)) {
+ try {
+ mCarBluetoothUserService.setProfilePriority(profile, device, priority);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling setProfilePriority");
+ }
+ // if any one of the uuid in uuidsTocheck is present, set the priority and break
+ break;
}
}
}
@@ -309,6 +397,9 @@
if (DBG) {
Log.d(TAG, "Connected to PerUserCarService");
}
+ // Get the BluetoothUserService and also setup the Bluetooth Connection Proxy for
+ // all profiles.
+ mCarBluetoothUserService = setupBluetoothUserService();
// re-initialize for current user.
initializeUserSpecificInfo();
}
@@ -415,9 +506,6 @@
setupBluetoothEventsIntentFilterLocked();
mConnectionInFlight = new ConnectionParams();
- // Get the BluetoothUserService and also setup the Bluetooth Connection Proxy for
- // all profiles.
- mCarBluetoothUserService = setupBluetoothUserService();
mUserSpecificInfoInitialized = true;
}
}
@@ -438,8 +526,11 @@
profileFilter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
profileFilter.addAction(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
profileFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- mContext.registerReceiverAsUser(mBluetoothBroadcastReceiver, UserHandle.CURRENT,
- profileFilter, null, null);
+ profileFilter.addAction(BluetoothDevice.ACTION_UUID);
+ if (mContext != null) {
+ mContext.registerReceiverAsUser(mBluetoothBroadcastReceiver, UserHandle.CURRENT,
+ profileFilter, null, null);
+ }
}
/**
@@ -646,7 +737,7 @@
return;
}
if (DBG) {
- Log.d(TAG, "BondState :" + bondState + " Device: " + device.getName());
+ Log.d(TAG, "BondState :" + bondState + " Device: " + device);
}
// Bonded devices are added to a profile's device list after the device CONNECTS on the
// profile. When unpaired, we remove the device from all of the profiles' device list.
diff --git a/service/src/com/android/car/CarBluetoothUserService.java b/service/src/com/android/car/CarBluetoothUserService.java
index 7ee02cf..55365a0 100644
--- a/service/src/com/android/car/CarBluetoothUserService.java
+++ b/service/src/com/android/car/CarBluetoothUserService.java
@@ -31,7 +31,7 @@
public class CarBluetoothUserService extends ICarBluetoothUserService.Stub {
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
private static final String TAG = "CarBluetoothUsrSvc";
private BluetoothAdapter mBluetoothAdapter = null;
private final PerUserCarService mService;
@@ -164,6 +164,36 @@
}
/**
+ * Set the priority of the given Bluetooth profile for the given remote device
+ * @param profile - Bluetooth profile
+ * @param device - remote Bluetooth device
+ * @param priority - priority to set
+ */
+ @Override
+ public void setProfilePriority(int profile, BluetoothDevice device, int priority) {
+ if (!isBluetoothConnectionProxyAvailable(profile)) {
+ Log.e(TAG, "Cannot connect to Profile. Proxy Unavailable");
+ return;
+ }
+ switch (profile) {
+ case BluetoothProfile.A2DP_SINK:
+ mBluetoothA2dpSink.setPriority(device, priority);
+ break;
+ case BluetoothProfile.HEADSET_CLIENT:
+ mBluetoothHeadsetClient.setPriority(device, priority);
+ break;
+ case BluetoothProfile.MAP_CLIENT:
+ mBluetoothMapClient.setPriority(device, priority);
+ break;
+ case BluetoothProfile.PBAP_CLIENT:
+ mBluetoothPbapClient.setPriority(device, priority);
+ break;
+ default:
+ Log.d(TAG, "Unknown Profile");
+ break;
+ }
+ }
+ /**
* All the BluetoothProfile.ServiceListeners to get the Profile Proxy objects
*/
private BluetoothProfile.ServiceListener mProfileListener =
diff --git a/tools/bootanalyze/bootanalyze.py b/tools/bootanalyze/bootanalyze.py
index 7010725..da874ce 100755
--- a/tools/bootanalyze/bootanalyze.py
+++ b/tools/bootanalyze/bootanalyze.py
@@ -680,7 +680,7 @@
return math.sqrt(variance)
def grab_bootchart(boot_chart_file_name):
- subprocess.call("./system/core/init/grab-bootchart.sh --no-viewer", shell=True)
+ subprocess.call("./system/core/init/grab-bootchart.sh", shell=True)
print "Saving boot chart as " + boot_chart_file_name + ".tgz"
subprocess.call('cp /tmp/android-bootchart/bootchart.tgz ./' + boot_chart_file_name + '.tgz',\
shell=True)