Add persistent state for Bluetooth high quality audio support
Defines the flags used in code and the Settings.Global key names for
persisting the following state for Bluetooth A2DP Sink devices:
-Whether the device supports optional codecs or not
-Whether optional codecs should be turned on for the device
For each of these two properties we model the state in the code as
yes/no/unknown, so that we can tailor the UI and behavior
accordingly.
Bug=37441685
Test: manually
Change-Id: I6bcd02fd7c95bef989575f3b13d4788dab61971a
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index d1ad8de..c58eaa1 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -136,6 +136,38 @@
*/
public static final int STATE_NOT_PLAYING = 11;
+ /**
+ * We don't have a stored preference for whether or not the given A2DP sink device supports
+ * optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
+
+ /**
+ * The given A2DP sink device does not support optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
+
+ /**
+ * The given A2DP sink device does support optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_SUPPORTED = 1;
+
+ /**
+ * We don't have a stored preference for whether optional codecs should be enabled or disabled
+ * for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
+
+ /**
+ * Optional codecs should be disabled for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
+
+ /**
+ * Optional codecs should be enabled for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
+
private Context mContext;
private ServiceListener mServiceListener;
private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
@@ -655,6 +687,88 @@
}
/**
+ * Returns whether this device supports optional codecs.
+ *
+ * @param device The device to check
+ * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
+ * OPTIONAL_CODECS_SUPPORTED.
+ *
+ * @hide
+ */
+ public int supportsOptionalCodecs(BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.supportsOptionalCodecs(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
+ return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Returns whether this device should have optional codecs enabled.
+ *
+ * @param device The device in question.
+ * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
+ * OPTIONAL_CODECS_PREF_DISABLED.
+ *
+ * @hide
+ */
+ public int getOptionalCodecsEnabled(BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.getOptionalCodecsEnabled(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return OPTIONAL_CODECS_PREF_UNKNOWN;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
+ return OPTIONAL_CODECS_PREF_UNKNOWN;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Sets a persistent preference for whether a given device should have optional codecs enabled.
+ *
+ * @param device The device to set this preference for.
+ * @param value Whether the optional codecs should be enabled for this device. This should be
+ * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
+ * OPTIONAL_CODECS_PREF_DISABLED.
+ * @hide
+ */
+ public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
+ try {
+ if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN &&
+ value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED &&
+ value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
+ Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
+ return;
+ }
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ mService.setOptionalCodecsEnabled(device, value);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
* Helper for converting a state to a string.
*
* For debug use only - strings are not internationalized.
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index a775a1f..1b533cb 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -42,4 +42,7 @@
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
oneway void enableOptionalCodecs();
oneway void disableOptionalCodecs();
+ int supportsOptionalCodecs(in BluetoothDevice device);
+ int getOptionalCodecsEnabled(in BluetoothDevice device);
+ oneway void setOptionalCodecsEnabled(in BluetoothDevice device, int value);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cbd41c3..3343ffe 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8922,6 +8922,12 @@
public static final String
BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_";
/** {@hide} */
+ public static final String BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX =
+ "bluetooth_a2dp_supports_optional_codecs_";
+ /** {@hide} */
+ public static final String BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX =
+ "bluetooth_a2dp_optional_codecs_enabled_";
+ /** {@hide} */
public static final String
BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
/** {@hide} */
@@ -9171,6 +9177,25 @@
}
/**
+ * Get the key that retrieves a bluetooth a2dp device's ability to support optional codecs.
+ * @hide
+ */
+ public static final String getBluetoothA2dpSupportsOptionalCodecsKey(String address) {
+ return BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX +
+ address.toUpperCase(Locale.ROOT);
+ }
+
+ /**
+ * Get the key that retrieves whether a bluetooth a2dp device should have optional codecs
+ * enabled.
+ * @hide
+ */
+ public static final String getBluetoothA2dpOptionalCodecsEnabledKey(String address) {
+ return BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX +
+ address.toUpperCase(Locale.ROOT);
+ }
+
+ /**
* Get the key that retrieves a bluetooth Input Device's priority.
* @hide
*/
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index ce951de..ea40fd5 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -329,6 +329,8 @@
SettingProto max_notification_enqueue_rate = 284;
SettingProto cell_on = 285;
SettingProto network_recommendations_package = 286;
+ SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
+ SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
}
message SecureSettingsProto {
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ad4afae..7d04954 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -109,6 +109,8 @@
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
Settings.Global.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX,
+ Settings.Global.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX,
+ Settings.Global.BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX,
Settings.Global.BLUETOOTH_DISABLED_PROFILES,
Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX,
Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX,