Merge "Improve A2DP autoreconnect policy"
diff --git a/Android.bp b/Android.bp
index dc523cc..347b22b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,7 +51,7 @@
"libbluetooth_headers",
],
include_dirs: [
- "system/bt/types",
+ "packages/modules/Bluetooth/system/types",
],
shared_libs: [
"libbase",
diff --git a/OWNERS b/OWNERS
index 2c1bdc4..cc15db5 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index bf6cba8..642e589 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -302,12 +302,22 @@
conn_id, status, p_data->handle, jb.get());
}
-void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle) {
+void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle,
+ uint16_t len, const uint8_t* value) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
+ ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
+ if (status == 0) { // Success
+ jb.reset(sCallbackEnv->NewByteArray(len));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, len, (jbyte*)value);
+ } else {
+ uint8_t value = 0;
+ jb.reset(sCallbackEnv->NewByteArray(1));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
+ }
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic,
- conn_id, status, handle);
+ conn_id, status, handle, jb.get());
}
void btgattc_execute_write_cb(int conn_id, int status) {
@@ -336,12 +346,22 @@
status, p_data.handle, jb.get());
}
-void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) {
+void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle,
+ uint16_t len, const uint8_t* value) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
+ ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
+ if (status == 0) { // Success
+ jb.reset(sCallbackEnv->NewByteArray(len));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, len, (jbyte*)value);
+ } else {
+ uint8_t value = 0;
+ jb.reset(sCallbackEnv->NewByteArray(1));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
+ }
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor, conn_id,
- status, handle);
+ status, handle, jb.get());
}
void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi,
@@ -983,7 +1003,7 @@
method_onReadCharacteristic =
env->GetMethodID(clazz, "onReadCharacteristic", "(III[B)V");
method_onWriteCharacteristic =
- env->GetMethodID(clazz, "onWriteCharacteristic", "(III)V");
+ env->GetMethodID(clazz, "onWriteCharacteristic", "(III[B)V");
method_onExecuteCompleted =
env->GetMethodID(clazz, "onExecuteCompleted", "(II)V");
method_onSearchCompleted =
@@ -991,7 +1011,7 @@
method_onReadDescriptor =
env->GetMethodID(clazz, "onReadDescriptor", "(III[B)V");
method_onWriteDescriptor =
- env->GetMethodID(clazz, "onWriteDescriptor", "(III)V");
+ env->GetMethodID(clazz, "onWriteDescriptor", "(III[B)V");
method_onNotify =
env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IZ[B)V");
method_onRegisterForNotifications =
diff --git a/src/com/android/bluetooth/a2dpsink/OWNERS b/src/com/android/bluetooth/a2dpsink/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/src/com/android/bluetooth/a2dpsink/OWNERS
+++ b/src/com/android/bluetooth/a2dpsink/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java b/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
index 922b151..75a760b 100644
--- a/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
+++ b/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
@@ -31,7 +31,7 @@
static final byte REV_SEEK = 4;
static final byte ERROR = -1;
- public long position = 0xFFFFFFFFFFFFFFFFL;
+ public long position = 0;
public long duration = 0x00L;
public byte state = STOPPED;
@@ -41,7 +41,7 @@
if (state == null) return ret;
ret.state = playbackStateToAvrcpState(state.getState());
- ret.position = state.getPosition();
+ ret.position = (state.getPosition() > 0) ? state.getPosition() : 0;
ret.duration = duration;
return ret;
}
diff --git a/src/com/android/bluetooth/avrcpcontroller/OWNERS b/src/com/android/bluetooth/avrcpcontroller/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/src/com/android/bluetooth/avrcpcontroller/OWNERS
+++ b/src/com/android/bluetooth/avrcpcontroller/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 9c4f6bb..f735641 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -98,6 +98,7 @@
import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.a2dpsink.A2dpSinkService;
+import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
import com.android.bluetooth.btservice.activityattribution.ActivityAttributionService;
import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService;
@@ -305,6 +306,8 @@
private volatile boolean mTestModeEnabled = false;
+ private MetricsLogger mMetricsLogger;
+
/**
* Register a {@link ProfileService} with AdapterService.
*
@@ -445,6 +448,7 @@
@Override
public void onCreate() {
super.onCreate();
+ initMetricsLogger();
debugLog("onCreate()");
mDeviceConfigListener.start();
mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());
@@ -456,8 +460,6 @@
mJniCallbacks = new JniCallbacks(this, mAdapterProperties);
mBluetoothKeystoreService = new BluetoothKeystoreService(isCommonCriteriaMode());
mBluetoothKeystoreService.start();
- mActivityAttributionService = new ActivityAttributionService();
- mActivityAttributionService.start();
int configCompareResult = mBluetoothKeystoreService.getCompareResult();
// Start tracking Binder latency for the bluetooth process.
@@ -512,6 +514,9 @@
mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this);
+ mActivityAttributionService = new ActivityAttributionService();
+ mActivityAttributionService.start();
+
setAdapterService(this);
invalidateBluetoothCaches();
@@ -582,6 +587,27 @@
}
};
+ private boolean initMetricsLogger() {
+ if (mMetricsLogger != null) {
+ return false;
+ }
+ mMetricsLogger = MetricsLogger.getInstance();
+ return mMetricsLogger.init(this);
+ }
+
+ private boolean closeMetricsLogger() {
+ if (mMetricsLogger == null) {
+ return false;
+ }
+ boolean result = mMetricsLogger.close();
+ mMetricsLogger = null;
+ return result;
+ }
+
+ public void setMetricsLogger(MetricsLogger metricsLogger) {
+ mMetricsLogger = metricsLogger;
+ }
+
void bringUpBle() {
debugLog("bleOnProcessStart()");
@@ -776,6 +802,8 @@
return;
}
+ closeMetricsLogger();
+
clearAdapterService(this);
mCleaningUp = true;
@@ -3817,7 +3845,7 @@
initFlags.add(String.format("%s=%s", LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG,
debugLoggingDisabledTags));
}
- if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, BTAA_HCI_LOG_FLAG, false)) {
+ if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, BTAA_HCI_LOG_FLAG, true)) {
initFlags.add(String.format("%s=%s", BTAA_HCI_LOG_FLAG, "true"));
}
return initFlags.toArray(new String[0]);
diff --git a/src/com/android/bluetooth/btservice/Config.java b/src/com/android/bluetooth/btservice/Config.java
index f4f6413..6b6f1cb 100644
--- a/src/com/android/bluetooth/btservice/Config.java
+++ b/src/com/android/bluetooth/btservice/Config.java
@@ -17,6 +17,7 @@
package com.android.bluetooth.btservice;
import android.bluetooth.BluetoothProfile;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
@@ -221,6 +222,11 @@
if (systemConfigManager == null) {
return null;
}
- return systemConfigManager.getEnabledComponentOverrides(ctx.getPackageName());
+ List<String> enabledComponent = new ArrayList<>();
+ for (ComponentName comp :
+ systemConfigManager.getEnabledComponentOverrides(ctx.getPackageName())) {
+ enabledComponent.add(comp.getClassName());
+ }
+ return enabledComponent;
}
}
diff --git a/src/com/android/bluetooth/btservice/MetricsLogger.java b/src/com/android/bluetooth/btservice/MetricsLogger.java
index b8a3d18..e47b303 100644
--- a/src/com/android/bluetooth/btservice/MetricsLogger.java
+++ b/src/com/android/bluetooth/btservice/MetricsLogger.java
@@ -15,18 +15,113 @@
*/
package com.android.bluetooth.btservice;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.SystemClock;
+import android.util.Log;
+
import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog;
import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats;
import com.android.bluetooth.BluetoothMetricsProto.ProfileId;
+import com.android.bluetooth.BluetoothStatsLog;
import java.util.HashMap;
/**
- * Class with static methods for logging metrics data
+ * Class of Bluetooth Metrics
*/
public class MetricsLogger {
+ private static final String TAG = "BluetoothMetricsLogger";
+
+ public static final boolean DEBUG = false;
+
+ /**
+ * Intent indicating Bluetooth counter metrics should send logs to BluetoothStatsLog
+ */
+ public static final String BLUETOOTH_COUNTER_METRICS_ACTION =
+ "com.android.bluetooth.map.BLUETOOTH_COUNTER_METRICS_ACTION";
+ // 6 hours timeout for counter metrics
+ private static final long BLUETOOTH_COUNTER_METRICS_ACTION_DURATION_MILLIS = 6L * 3600L * 1000L;
+
private static final HashMap<ProfileId, Integer> sProfileConnectionCounts = new HashMap<>();
+ HashMap<Integer, Long> mCounters = new HashMap<>();
+ private static MetricsLogger sInstance = null;
+ private Context mContext = null;
+ private AlarmManager mAlarmManager = null;
+ private boolean mInitialized = false;
+ static final private Object mLock = new Object();
+
+ private BroadcastReceiver mDrainReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (DEBUG) {
+ Log.d(TAG, "onReceive: " + action);
+ }
+ if (action.equals(BLUETOOTH_COUNTER_METRICS_ACTION)) {
+ drainBufferedCounters();
+ }
+ }
+ };
+
+ public static MetricsLogger getInstance() {
+ if (sInstance == null) {
+ synchronized (mLock) {
+ if (sInstance == null) {
+ sInstance = new MetricsLogger();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ public boolean isInitialized() {
+ return mInitialized;
+ }
+
+ public boolean init(Context context) {
+ if (mInitialized) {
+ return false;
+ }
+ mInitialized = true;
+ mContext = context;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BLUETOOTH_COUNTER_METRICS_ACTION);
+ mContext.registerReceiver(mDrainReceiver, filter);
+ scheduleDrains();
+ return true;
+ }
+
+ public boolean count(int key, long count) {
+ if (!mInitialized) {
+ Log.w(TAG, "MetricsLogger isn't initialized");
+ return false;
+ }
+ if (count <= 0) {
+ Log.w(TAG, "count is not larger than 0. count: " + count + " key: " + key);
+ return false;
+ }
+ long total = 0;
+
+ synchronized (mLock) {
+ if (mCounters.containsKey(key)) {
+ total = mCounters.get(key);
+ }
+ if (Long.MAX_VALUE - total < count) {
+ Log.w(TAG, "count overflows. count: " + count + " current total: " + total);
+ mCounters.put(key, Long.MAX_VALUE);
+ return false;
+ }
+ mCounters.put(key, total + count);
+ }
+ return true;
+ }
+
/**
* Log profile connection event by incrementing an internal counter for that profile.
* This log persists over adapter enable/disable and only get cleared when metrics are
@@ -57,4 +152,60 @@
sProfileConnectionCounts.clear();
}
}
+
+ protected void scheduleDrains() {
+ if (DEBUG) {
+ Log.d(TAG, "setCounterMetricsAlarm()");
+ }
+ if (mAlarmManager == null) {
+ mAlarmManager = mContext.getSystemService(AlarmManager.class);
+ }
+ mAlarmManager.setRepeating(
+ AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime(),
+ BLUETOOTH_COUNTER_METRICS_ACTION_DURATION_MILLIS,
+ getDrainIntent());
+ }
+
+ protected void writeCounter(int key, long count) {
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_CODE_PATH_COUNTER, key, count);
+ }
+
+ protected void drainBufferedCounters() {
+ Log.i(TAG, "drainBufferedCounters().");
+ synchronized (mLock) {
+ // send mCounters to westworld
+ for (int key : mCounters.keySet()) {
+ writeCounter(key, mCounters.get(key));
+ }
+ mCounters.clear();
+ }
+ }
+
+ public boolean close() {
+ if (!mInitialized) {
+ return false;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "close()");
+ }
+ cancelPendingDrain();
+ drainBufferedCounters();
+ mAlarmManager = null;
+ mContext = null;
+ mInitialized = false;
+ return true;
+ }
+ protected void cancelPendingDrain() {
+ PendingIntent pIntent = getDrainIntent();
+ pIntent.cancel();
+ mAlarmManager.cancel(pIntent);
+ }
+
+ private PendingIntent getDrainIntent() {
+ Intent counterMetricsIntent = new Intent(BLUETOOTH_COUNTER_METRICS_ACTION);
+ return PendingIntent.getBroadcast(
+ mContext, 0, counterMetricsIntent, PendingIntent.FLAG_IMMUTABLE);
+ }
}
diff --git a/src/com/android/bluetooth/btservice/PhonePolicy.java b/src/com/android/bluetooth/btservice/PhonePolicy.java
index 286c344..94a5355 100644
--- a/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -19,12 +19,14 @@
import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
+import android.bluetooth.BluetoothVolumeControl;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -39,10 +41,13 @@
import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
+import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hid.HidHostService;
+import com.android.bluetooth.le_audio.LeAudioService;
import com.android.bluetooth.pan.PanService;
+import com.android.bluetooth.vc.VolumeControlService;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -118,11 +123,21 @@
BluetoothProfile.A2DP, -1, // No-op argument
intent).sendToTarget();
break;
+ case BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.CSIP_SET_COORDINATOR, -1, // No-op argument
+ intent).sendToTarget();
+ break;
case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
BluetoothProfile.LE_AUDIO, -1, // No-op argument
intent).sendToTarget();
break;
+ case BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.VOLUME_CONTROL, -1, // No-op argument
+ intent).sendToTarget();
+ break;
case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED,
BluetoothProfile.A2DP, -1, // No-op argument
@@ -242,6 +257,8 @@
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothCsipSetCoordinator.ACTION_CSIS_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -274,6 +291,11 @@
HeadsetService headsetService = mFactory.getHeadsetService();
PanService panService = mFactory.getPanService();
HearingAidService hearingAidService = mFactory.getHearingAidService();
+ LeAudioService leAudioService = mFactory.getLeAudioService();
+ CsipSetCoordinatorService csipSetCooridnatorService =
+ mFactory.getCsipSetCoordinatorService();
+ VolumeControlService volumeControlService =
+ mFactory.getVolumeControlService();
// Set profile priorities only for the profiles discovered on the remote device.
// This avoids needless auto-connect attempts to profiles non-existent on the remote device
@@ -302,6 +324,14 @@
BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
+ if ((csipSetCooridnatorService != null)
+ && (Utils.arrayContains(uuids, BluetoothUuid.COORDINATED_SET))
+ && (csipSetCooridnatorService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
+ mAdapterService.getDatabase().setProfileConnectionPolicy(device,
+ BluetoothProfile.CSIP_SET_COORDINATOR, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ }
+
if ((panService != null) && (Utils.arrayContains(uuids, BluetoothUuid.PANU) && (
panService.getConnectionPolicy(device)
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN)
@@ -311,6 +341,14 @@
BluetoothProfile.PAN, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
+ if ((leAudioService != null) && Utils.arrayContains(uuids,
+ BluetoothUuid.LE_AUDIO) && (leAudioService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
+ debugLog("setting le audio profile priority for device " + device);
+ mAdapterService.getDatabase().setProfileConnectionPolicy(device,
+ BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ }
+
if ((hearingAidService != null) && Utils.arrayContains(uuids,
BluetoothUuid.HEARING_AID) && (hearingAidService.getConnectionPolicy(device)
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
@@ -318,6 +356,14 @@
mAdapterService.getDatabase().setProfileConnectionPolicy(device,
BluetoothProfile.HEARING_AID, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
+
+ if ((volumeControlService != null) && Utils.arrayContains(uuids,
+ BluetoothUuid.VOLUME_CONTROL) && (volumeControlService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
+ debugLog("setting volume control profile priority for device " + device);
+ mAdapterService.getDatabase().setProfileConnectionPolicy(device,
+ BluetoothProfile.VOLUME_CONTROL, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ }
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
@@ -326,7 +372,9 @@
debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", "
+ prevState + " -> " + nextState);
if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)
- || (profileId == BluetoothProfile.LE_AUDIO))) {
+ || (profileId == BluetoothProfile.LE_AUDIO)
+ || (profileId == BluetoothProfile.CSIP_SET_COORDINATOR)
+ || (profileId == BluetoothProfile.VOLUME_CONTROL))) {
if (nextState == BluetoothProfile.STATE_CONNECTED) {
switch (profileId) {
case BluetoothProfile.A2DP:
@@ -375,6 +423,9 @@
HeadsetService hsService = mFactory.getHeadsetService();
A2dpService a2dpService = mFactory.getA2dpService();
PanService panService = mFactory.getPanService();
+ LeAudioService leAudioService = mFactory.getLeAudioService();
+ CsipSetCoordinatorService csipSetCooridnatorService =
+ mFactory.getCsipSetCoordinatorService();
if (hsService != null) {
List<BluetoothDevice> hsConnDevList = hsService.getConnectedDevices();
@@ -386,11 +437,21 @@
allProfilesEmpty &= a2dpConnDevList.isEmpty();
atLeastOneProfileConnectedForDevice |= a2dpConnDevList.contains(device);
}
+ if (csipSetCooridnatorService != null) {
+ List<BluetoothDevice> csipConnDevList = csipSetCooridnatorService.getConnectedDevices();
+ allProfilesEmpty &= csipConnDevList.isEmpty();
+ atLeastOneProfileConnectedForDevice |= csipConnDevList.contains(device);
+ }
if (panService != null) {
List<BluetoothDevice> panConnDevList = panService.getConnectedDevices();
allProfilesEmpty &= panConnDevList.isEmpty();
atLeastOneProfileConnectedForDevice |= panConnDevList.contains(device);
}
+ if (leAudioService != null) {
+ List<BluetoothDevice> leAudioConnDevList = leAudioService.getConnectedDevices();
+ allProfilesEmpty &= leAudioConnDevList.isEmpty();
+ atLeastOneProfileConnectedForDevice |= leAudioConnDevList.contains(device);
+ }
if (!atLeastOneProfileConnectedForDevice) {
// Consider this device as fully disconnected, don't bother connecting others
@@ -507,6 +568,11 @@
HeadsetService hsService = mFactory.getHeadsetService();
A2dpService a2dpService = mFactory.getA2dpService();
PanService panService = mFactory.getPanService();
+ LeAudioService leAudioService = mFactory.getLeAudioService();
+ CsipSetCoordinatorService csipSetCooridnatorService =
+ mFactory.getCsipSetCoordinatorService();
+ VolumeControlService volumeControlService =
+ mFactory.getVolumeControlService();
if (hsService != null) {
if (!mHeadsetRetrySet.contains(device) && (hsService.getConnectionPolicy(device)
@@ -540,6 +606,36 @@
panService.connect(device);
}
}
+ if (leAudioService != null) {
+ List<BluetoothDevice> leAudioConnDevList = leAudioService.getConnectedDevices();
+ if (!leAudioConnDevList.contains(device) && (leAudioService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ && (leAudioService.getConnectionState(device)
+ == BluetoothProfile.STATE_DISCONNECTED)) {
+ debugLog("Retrying connection to LEAudio with device " + device);
+ leAudioService.connect(device);
+ }
+ }
+ if (csipSetCooridnatorService != null) {
+ List<BluetoothDevice> csipConnDevList = csipSetCooridnatorService.getConnectedDevices();
+ if (!csipConnDevList.contains(device) && (csipSetCooridnatorService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ && (csipSetCooridnatorService.getConnectionState(device)
+ == BluetoothProfile.STATE_DISCONNECTED)) {
+ debugLog("Retrying connection to CSIP with device " + device);
+ csipSetCooridnatorService.connect(device);
+ }
+ }
+ if (volumeControlService != null) {
+ List<BluetoothDevice> vcConnDevList = volumeControlService.getConnectedDevices();
+ if (!vcConnDevList.contains(device) && (volumeControlService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ && (volumeControlService.getConnectionState(device)
+ == BluetoothProfile.STATE_DISCONNECTED)) {
+ debugLog("Retrying connection to CSIP with device " + device);
+ volumeControlService.connect(device);
+ }
+ }
}
private static void debugLog(String msg) {
diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java
index a28105a..2f0a8d4 100644
--- a/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -600,6 +600,9 @@
if (sAdapterService.getState() == BluetoothAdapter.STATE_ON) {
sAdapterService.deviceUuidUpdated(bdDevice);
sendUuidIntent(bdDevice, device);
+ } else if (sAdapterService.getState()
+ == BluetoothAdapter.STATE_BLE_ON) {
+ sAdapterService.deviceUuidUpdated(bdDevice);
}
break;
case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE:
diff --git a/src/com/android/bluetooth/btservice/ServiceFactory.java b/src/com/android/bluetooth/btservice/ServiceFactory.java
index fd1b6d8..6842dc0 100644
--- a/src/com/android/bluetooth/btservice/ServiceFactory.java
+++ b/src/com/android/bluetooth/btservice/ServiceFactory.java
@@ -18,6 +18,7 @@
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.avrcp.AvrcpTargetService;
+import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hid.HidDeviceService;
@@ -25,6 +26,7 @@
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.bluetooth.mcp.McpService;
import com.android.bluetooth.pan.PanService;
+import com.android.bluetooth.vc.VolumeControlService;
// Factory class to create instances of static services. Useful in mocking the service objects.
public class ServiceFactory {
@@ -32,6 +34,10 @@
return A2dpService.getA2dpService();
}
+ public CsipSetCoordinatorService getCsipSetCoordinatorService() {
+ return CsipSetCoordinatorService.getCsipSetCoordinatorService();
+ }
+
public HeadsetService getHeadsetService() {
return HeadsetService.getHeadsetService();
}
@@ -63,4 +69,8 @@
public McpService getMcpService() {
return McpService.getMcpService();
}
+
+ public VolumeControlService getVolumeControlService() {
+ return VolumeControlService.getVolumeControlService();
+ }
}
diff --git a/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
index 61f4cdf..7fe1345 100644
--- a/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
+++ b/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
@@ -284,7 +284,7 @@
return true;
}
- List<BluetoothDevice> getConnectedDevices() {
+ public List<BluetoothDevice> getConnectedDevices() {
enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission");
synchronized (mStateMachines) {
List<BluetoothDevice> devices = new ArrayList<>();
diff --git a/src/com/android/bluetooth/gatt/CallbackInfo.java b/src/com/android/bluetooth/gatt/CallbackInfo.java
index 330422d..f6035b3 100644
--- a/src/com/android/bluetooth/gatt/CallbackInfo.java
+++ b/src/com/android/bluetooth/gatt/CallbackInfo.java
@@ -26,16 +26,38 @@
public String address;
public int status;
public int handle;
+ public byte[] value;
- CallbackInfo(String address, int status, int handle) {
+ static class Builder {
+ private String mAddress;
+ private int mStatus;
+ private int mHandle;
+ private byte[] mValue;
+
+ Builder(String address, int status) {
+ mAddress = address;
+ mStatus = status;
+ }
+
+ Builder setHandle(int handle) {
+ mHandle = handle;
+ return this;
+ }
+
+ Builder setValue(byte[] value) {
+ mValue = value;
+ return this;
+ }
+
+ CallbackInfo build() {
+ return new CallbackInfo(mAddress, mStatus, mHandle, mValue);
+ }
+ }
+
+ private CallbackInfo(String address, int status, int handle, byte[] value) {
this.address = address;
this.status = status;
this.handle = handle;
}
-
- CallbackInfo(String address, int status) {
- this.address = address;
- this.status = status;
- }
}
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 17f7fca..e7b6aac 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -30,6 +30,7 @@
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
@@ -734,7 +735,7 @@
int authReq, byte[] value, AttributionSource attributionSource) {
GattService service = getService();
if (service == null) {
- return BluetoothGatt.GATT_WRITE_REQUEST_FAIL;
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
}
return service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value,
attributionSource);
@@ -751,13 +752,14 @@
}
@Override
- public void writeDescriptor(int clientIf, String address, int handle, int authReq,
+ public int writeDescriptor(int clientIf, String address, int handle, int authReq,
byte[] value, AttributionSource attributionSource) {
GattService service = getService();
if (service == null) {
- return;
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
}
- service.writeDescriptor(clientIf, address, handle, authReq, value, attributionSource);
+ return service.writeDescriptor(clientIf, address, handle, authReq, value,
+ attributionSource);
}
@Override
@@ -1694,7 +1696,8 @@
}
}
- void onWriteCharacteristic(int connId, int status, int handle) throws RemoteException {
+ void onWriteCharacteristic(int connId, int status, int handle, byte[] data)
+ throws RemoteException {
String address = mClientMap.addressByConnId(connId);
synchronized (mPermits) {
Log.d(TAG, "onWriteCharacteristic() - increasing permit for address="
@@ -1703,7 +1706,8 @@
}
if (VDBG) {
- Log.d(TAG, "onWriteCharacteristic() - address=" + address + ", status=" + status);
+ Log.d(TAG, "onWriteCharacteristic() - address=" + address + ", status=" + status
+ + ", length=" + data.length);
}
ClientMap.App app = mClientMap.getByConnId(connId);
@@ -1712,12 +1716,15 @@
}
if (!app.isCongested) {
- app.callback.onCharacteristicWrite(address, status, handle);
+ app.callback.onCharacteristicWrite(address, status, handle, data);
} else {
if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
status = BluetoothGatt.GATT_SUCCESS;
}
- CallbackInfo callbackInfo = new CallbackInfo(address, status, handle);
+ CallbackInfo callbackInfo = new CallbackInfo.Builder(address, status)
+ .setHandle(handle)
+ .setValue(data)
+ .build();
app.queueCallback(callbackInfo);
}
}
@@ -1749,16 +1756,18 @@
}
}
- void onWriteDescriptor(int connId, int status, int handle) throws RemoteException {
+ void onWriteDescriptor(int connId, int status, int handle, byte[] data)
+ throws RemoteException {
String address = mClientMap.addressByConnId(connId);
if (VDBG) {
- Log.d(TAG, "onWriteDescriptor() - address=" + address + ", status=" + status);
+ Log.d(TAG, "onWriteDescriptor() - address=" + address + ", status=" + status
+ + ", length=" + data.length);
}
ClientMap.App app = mClientMap.getByConnId(connId);
if (app != null) {
- app.callback.onDescriptorWrite(address, status, handle);
+ app.callback.onDescriptorWrite(address, status, handle, data);
}
}
@@ -2181,7 +2190,7 @@
return;
}
app.callback.onCharacteristicWrite(callbackInfo.address, callbackInfo.status,
- callbackInfo.handle);
+ callbackInfo.handle, callbackInfo.value);
}
}
}
@@ -2915,7 +2924,7 @@
byte[] value, AttributionSource attributionSource) {
if (!Utils.checkConnectPermissionForDataDelivery(
this, attributionSource, "GattService writeCharacteristic")) {
- return BluetoothGatt.GATT_WRITE_REQUEST_FAIL;
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
}
if (VDBG) {
@@ -2929,12 +2938,12 @@
Integer connId = mClientMap.connIdByAddress(clientIf, address);
if (connId == null) {
Log.e(TAG, "writeCharacteristic() - No connection for " + address + "...");
- return BluetoothGatt.GATT_WRITE_REQUEST_FAIL;
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED;
}
if (!permissionCheck(connId, handle)) {
Log.w(TAG, "writeCharacteristic() - permission check failed!");
- return BluetoothGatt.GATT_WRITE_REQUEST_FAIL;
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION;
}
Log.d(TAG, "writeCharacteristic() - trying to acquire permit.");
@@ -2943,19 +2952,19 @@
AtomicBoolean atomicBoolean = mPermits.get(address);
if (atomicBoolean == null) {
Log.d(TAG, "writeCharacteristic() - atomicBoolean uninitialized!");
- return BluetoothGatt.GATT_WRITE_REQUEST_FAIL;
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED;
}
boolean success = atomicBoolean.get();
if (!success) {
- Log.d(TAG, "writeCharacteristic() - no permit available.");
- return BluetoothGatt.GATT_WRITE_REQUEST_BUSY;
+ Log.d(TAG, "writeCharacteristic() - no permit available.");
+ return BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY;
}
atomicBoolean.set(false);
}
gattClientWriteCharacteristicNative(connId, handle, writeType, authReq, value);
- return BluetoothGatt.GATT_WRITE_REQUEST_SUCCESS;
+ return BluetoothStatusCodes.SUCCESS;
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -2985,11 +2994,11 @@
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- void writeDescriptor(int clientIf, String address, int handle, int authReq, byte[] value,
+ int writeDescriptor(int clientIf, String address, int handle, int authReq, byte[] value,
AttributionSource attributionSource) {
if (!Utils.checkConnectPermissionForDataDelivery(
this, attributionSource, "GattService writeDescriptor")) {
- return;
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
}
if (VDBG) {
Log.d(TAG, "writeDescriptor() - address=" + address);
@@ -2998,15 +3007,16 @@
Integer connId = mClientMap.connIdByAddress(clientIf, address);
if (connId == null) {
Log.e(TAG, "writeDescriptor() - No connection for " + address + "...");
- return;
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED;
}
if (!permissionCheck(connId, handle)) {
Log.w(TAG, "writeDescriptor() - permission check failed!");
- return;
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION;
}
gattClientWriteDescriptorNative(connId, handle, authReq, value);
+ return BluetoothStatusCodes.SUCCESS;
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -3410,7 +3420,7 @@
if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
status = BluetoothGatt.GATT_SUCCESS;
}
- app.queueCallback(new CallbackInfo(address, status));
+ app.queueCallback(new CallbackInfo.Builder(address, status).build());
}
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
index 50094cf1..4bf7530 100644
--- a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
+++ b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
@@ -70,6 +70,8 @@
private final HashMap<BluetoothDevice, Integer> mDeviceEventMap = new HashMap<>();
private PhoneStateListener mPhoneStateListener;
private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
+ // TODO(b/205585585): Re-enable SignalStrengthUpdateRequest to support "always report signal
+ // strength" when the crash is fixed.
HeadsetPhoneState(HeadsetService headsetService) {
Objects.requireNonNull(headsetService, "headsetService is null");
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index 9548eac..7c3784e 100644
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -1645,7 +1645,7 @@
// Suspend A2DP when call about is about to become active
if (mActiveDevice != null && callState != HeadsetHalConstants.CALL_STATE_DISCONNECTED
&& !mSystemInterface.isCallIdle() && isCallIdleBefore) {
- mSystemInterface.getAudioManager().setParameters("A2dpSuspended=true");
+ mSystemInterface.getAudioManager().setA2dpSuspended(true);
}
});
doForEachConnectedStateMachine(
@@ -1655,7 +1655,7 @@
if (callState == HeadsetHalConstants.CALL_STATE_IDLE
&& mSystemInterface.isCallIdle() && !isAudioOn()) {
// Resume A2DP when call ended and SCO is not connected
- mSystemInterface.getAudioManager().setParameters("A2dpSuspended=false");
+ mSystemInterface.getAudioManager().setA2dpSuspended(false);
}
});
@@ -1813,7 +1813,7 @@
}
// Unsuspend A2DP when SCO connection is gone and call state is idle
if (mSystemInterface.isCallIdle()) {
- mSystemInterface.getAudioManager().setParameters("A2dpSuspended=false");
+ mSystemInterface.getAudioManager().setA2dpSuspended(false);
}
}
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index cddb9cc..bbc7878 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -80,12 +80,6 @@
private static final String TAG = "HeadsetStateMachine";
private static final boolean DBG = false;
- private static final String HEADSET_NAME = "bt_headset_name";
- private static final String HEADSET_NREC = "bt_headset_nrec";
- private static final String HEADSET_WBS = "bt_wbs";
- private static final String HEADSET_AUDIO_FEATURE_ON = "on";
- private static final String HEADSET_AUDIO_FEATURE_OFF = "off";
-
static final int CONNECT = 1;
static final int DISCONNECT = 2;
static final int CONNECT_AUDIO = 3;
@@ -147,8 +141,9 @@
private HeadsetAgIndicatorEnableState mAgIndicatorEnableState;
// The timestamp when the device entered connecting/connected state
private long mConnectingTimestampMs = Long.MIN_VALUE;
- // Audio Parameters like NREC
- private final HashMap<String, String> mAudioParams = new HashMap<>();
+ // Audio Parameters
+ private boolean mHasNrecEnabled = false;
+ private boolean mHasWbsEnabled = false;
// AT Phone book keeps a group of states used by AT+CPBR commands
private final AtPhonebook mPhonebook;
// HSP specific
@@ -227,7 +222,8 @@
if (mPhonebook != null) {
mPhonebook.cleanup();
}
- mAudioParams.clear();
+ mHasWbsEnabled = false;
+ mHasNrecEnabled = false;
}
public void dump(StringBuilder sb) {
@@ -322,8 +318,7 @@
BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_SCO_CONNECTION_STATE_CHANGED,
mAdapterService.obfuscateAddress(device),
getConnectionStateFromAudioState(toState),
- TextUtils.equals(mAudioParams.get(HEADSET_WBS), HEADSET_AUDIO_FEATURE_ON)
- ? BluetoothHfpProtoEnums.SCO_CODEC_MSBC
+ mHasWbsEnabled ? BluetoothHfpProtoEnums.SCO_CODEC_MSBC
: BluetoothHfpProtoEnums.SCO_CODEC_CVSD,
mAdapterService.getMetricId(device));
mHeadsetService.onAudioStateChangedFromStateMachine(device, fromState, toState);
@@ -456,7 +451,8 @@
mPhonebook.resetAtState();
updateAgIndicatorEnableState(null);
mNeedDialingOutReply = false;
- mAudioParams.clear();
+ mHasWbsEnabled = false;
+ mHasNrecEnabled = false;
broadcastStateTransitions();
// Remove the state machine for unbonded devices
if (mPrevState != null
@@ -1083,9 +1079,9 @@
break;
case CONNECT_AUDIO:
stateLogD("CONNECT_AUDIO, device=" + mDevice);
- mSystemInterface.getAudioManager().setParameters("A2dpSuspended=true");
+ mSystemInterface.getAudioManager().setA2dpSuspended(true);
if (!mNativeInterface.connectAudio(mDevice)) {
- mSystemInterface.getAudioManager().setParameters("A2dpSuspended=false");
+ mSystemInterface.getAudioManager().setA2dpSuspended(false);
stateLogE("Failed to connect SCO audio for " + mDevice);
// No state change involved, fire broadcast immediately
broadcastAudioState(mDevice, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
@@ -1530,15 +1526,12 @@
}
private void setAudioParameters() {
- String keyValuePairs = String.join(";", new String[]{
- HEADSET_NAME + "=" + getCurrentDeviceName(),
- HEADSET_NREC + "=" + mAudioParams.getOrDefault(HEADSET_NREC,
- HEADSET_AUDIO_FEATURE_OFF),
- HEADSET_WBS + "=" + mAudioParams.getOrDefault(HEADSET_WBS,
- HEADSET_AUDIO_FEATURE_OFF)
- });
- Log.i(TAG, "setAudioParameters for " + mDevice + ": " + keyValuePairs);
- mSystemInterface.getAudioManager().setParameters(keyValuePairs);
+ AudioManager am = mSystemInterface.getAudioManager();
+ Log.i(TAG, "setAudioParameters for " + mDevice + ":"
+ + " Name=" + getCurrentDeviceName()
+ + " hasNrecEnabled=" + mHasNrecEnabled
+ + " hasWbsEnabled=" + mHasWbsEnabled);
+ am.setBluetoothHeadsetProperties(getCurrentDeviceName(), mHasNrecEnabled, mHasWbsEnabled);
}
private String parseUnknownAt(String atString) {
@@ -1667,32 +1660,28 @@
}
private void processNoiseReductionEvent(boolean enable) {
- String prevNrec = mAudioParams.getOrDefault(HEADSET_NREC, HEADSET_AUDIO_FEATURE_OFF);
- String newNrec = enable ? HEADSET_AUDIO_FEATURE_ON : HEADSET_AUDIO_FEATURE_OFF;
- mAudioParams.put(HEADSET_NREC, newNrec);
- log("processNoiseReductionEvent: " + HEADSET_NREC + " change " + prevNrec + " -> "
- + newNrec);
+ log("processNoiseReductionEvent: " + mHasNrecEnabled + " -> " + enable);
+ mHasNrecEnabled = enable;
if (getAudioState() == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
setAudioParameters();
}
}
private void processWBSEvent(int wbsConfig) {
- String prevWbs = mAudioParams.getOrDefault(HEADSET_WBS, HEADSET_AUDIO_FEATURE_OFF);
+ boolean prevWbs = mHasWbsEnabled;
switch (wbsConfig) {
case HeadsetHalConstants.BTHF_WBS_YES:
- mAudioParams.put(HEADSET_WBS, HEADSET_AUDIO_FEATURE_ON);
+ mHasWbsEnabled = true;
break;
case HeadsetHalConstants.BTHF_WBS_NO:
case HeadsetHalConstants.BTHF_WBS_NONE:
- mAudioParams.put(HEADSET_WBS, HEADSET_AUDIO_FEATURE_OFF);
+ mHasWbsEnabled = false;
break;
default:
Log.e(TAG, "processWBSEvent: unknown wbsConfig " + wbsConfig);
return;
}
- log("processWBSEvent: " + HEADSET_NREC + " change " + prevWbs + " -> " + mAudioParams.get(
- HEADSET_WBS));
+ log("processWBSEvent: " + prevWbs + " -> " + mHasWbsEnabled);
}
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -2075,7 +2064,7 @@
events |= PhoneStateListener.LISTEN_SERVICE_STATE;
}
if (mAgIndicatorEnableState != null && mAgIndicatorEnableState.signal) {
- events |= PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH;
+ events |= PhoneStateListener.LISTEN_SIGNAL_STRENGTHS;
}
mSystemInterface.getHeadsetPhoneState().listenForPhoneState(mDevice, events);
}
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
index 23e8e58..8c45847 100644
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
@@ -111,7 +111,7 @@
Log.e(TAG, "AudioManager service doesn't exist?");
} else {
// start AudioManager in a known state
- mAudioManager.setParameters("hfp_enable=false");
+ mAudioManager.setHfpEnabled(false);
}
mSmFactory = new HeadsetClientStateMachineFactory();
@@ -200,7 +200,7 @@
"Setting volume to audio manager: " + streamValue + " hands free: "
+ hfVol);
}
- mAudioManager.setParameters("hfp_volume=" + hfVol);
+ mAudioManager.setHfpVolume(hfVol);
synchronized (mStateMachineMap) {
for (HeadsetClientStateMachine sm : mStateMachineMap.values()) {
if (sm != null) {
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index 9f724a6..13eeee9 100644
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -815,9 +815,9 @@
}
logD("hfp_enable=" + enable);
if (enable && !sAudioIsRouted) {
- mAudioManager.setParameters("hfp_enable=true");
+ mAudioManager.setHfpEnabled(true);
} else if (!enable) {
- mAudioManager.setParameters("hfp_enable=false");
+ mAudioManager.setHfpEnabled(false);
}
sAudioIsRouted = enable;
}
@@ -1592,7 +1592,7 @@
// routing is handled by the bluetooth stack itself. The only reason to do so is
// because Bluetooth SCO connection from the HF role is not entirely supported
// for routing and volume purposes.
- // NOTE: All calls here are routed via the setParameters which changes the
+ // NOTE: All calls here are routed via AudioManager methods which changes the
// routing at the Audio HAL level.
if (mService.isScoRouted()) {
@@ -1614,15 +1614,15 @@
logD("hfp_enable=true mAudioWbs is " + mAudioWbs);
if (mAudioWbs) {
logD("Setting sampling rate as 16000");
- mAudioManager.setParameters("hfp_set_sampling_rate=16000");
+ mAudioManager.setHfpSamplingRate(16000);
} else {
logD("Setting sampling rate as 8000");
- mAudioManager.setParameters("hfp_set_sampling_rate=8000");
+ mAudioManager.setHfpSamplingRate(8000);
}
logD("hf_volume " + hfVol);
routeHfpAudio(true);
mAudioFocusRequest = requestAudioFocus();
- mAudioManager.setParameters("hfp_volume=" + hfVol);
+ mAudioManager.setHfpVolume(hfVol);
transitionTo(mAudioOn);
break;
diff --git a/src/com/android/bluetooth/hfpclient/OWNERS b/src/com/android/bluetooth/hfpclient/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/src/com/android/bluetooth/hfpclient/OWNERS
+++ b/src/com/android/bluetooth/hfpclient/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/src/com/android/bluetooth/le_audio/LeAudioService.java b/src/com/android/bluetooth/le_audio/LeAudioService.java
index b03b161..da5828e 100644
--- a/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -421,12 +421,6 @@
return false;
}
- int groupId = getGroupId(device);
-
- if (DBG) {
- Log.d(TAG, "connect(): " + device + " group id: " + groupId);
- }
-
synchronized (mStateMachines) {
LeAudioStateMachine sm = getOrCreateStateMachine(device);
if (sm == null) {
@@ -437,25 +431,7 @@
}
// Connect other devices from this group
- if (groupId != LE_AUDIO_GROUP_ID_INVALID) {
- for (BluetoothDevice storedDevice : mDeviceGroupIdMap.keySet()) {
- if (device.equals(storedDevice)) {
- continue;
- }
- if (getGroupId(storedDevice) != groupId) {
- continue;
- }
- synchronized (mStateMachines) {
- LeAudioStateMachine sm = getOrCreateStateMachine(storedDevice);
- if (sm == null) {
- Log.e(TAG, "Ignored connect request for " + storedDevice
- + " : no state machine");
- continue;
- }
- sm.sendMessage(LeAudioStateMachine.CONNECT);
- }
- }
- }
+ connectSet(device);
return true;
}
@@ -507,7 +483,7 @@
return true;
}
- List<BluetoothDevice> getConnectedDevices() {
+ public List<BluetoothDevice> getConnectedDevices() {
synchronized (mStateMachines) {
List<BluetoothDevice> devices = new ArrayList<>();
for (LeAudioStateMachine sm : mStateMachines.values()) {
@@ -705,7 +681,7 @@
* - If device stops supporting input
*/
boolean inActiveDeviceReplace = (device != mPreviousAudioInDevice);
- if (mPreviousAudioInDevice != null) {
+ if (inActiveDeviceReplace && (mPreviousAudioInDevice != null)) {
mAudioManager.setBluetoothLeAudioInDeviceConnectionState(
mPreviousAudioInDevice, BluetoothProfile.STATE_DISCONNECTED);
}
@@ -749,7 +725,7 @@
if (device != null && mPreviousAudioOutDevice != null) {
int previousGroupId = getGroupId(mPreviousAudioOutDevice);
if (previousGroupId == groupId) {
- /* This is thes same group as aleady notified to the system.
+ /* This is the same group as already notified to the system.
* Therefore do not change the device we have connected to the group,
* unless, previous one is disconnected now
*/
@@ -763,7 +739,7 @@
* - If device stops supporting output
*/
boolean outActiveDeviceReplace = (device != mPreviousAudioOutDevice);
- if (mPreviousAudioOutDevice != null) {
+ if (outActiveDeviceReplace && (mPreviousAudioOutDevice != null)) {
boolean suppressNoisyIntent =
(getConnectionState(mPreviousAudioOutDevice) ==
BluetoothProfile.STATE_CONNECTED);
@@ -889,6 +865,42 @@
return activeDevices;
}
+ void connectSet(BluetoothDevice device) {
+ int groupId = getGroupId(device);
+ if (groupId == LE_AUDIO_GROUP_ID_INVALID) {
+ return;
+ }
+
+ if (DBG) {
+ Log.d(TAG, "connect() others from group id: " + groupId);
+ }
+
+ for (BluetoothDevice storedDevice : mDeviceGroupIdMap.keySet()) {
+ if (device.equals(storedDevice)) {
+ continue;
+ }
+
+ if (getGroupId(storedDevice) != groupId) {
+ continue;
+ }
+
+ if (DBG) {
+ Log.d(TAG, "connect(): " + device);
+ }
+
+ synchronized (mStateMachines) {
+ LeAudioStateMachine sm = getOrCreateStateMachine(storedDevice);
+ if (sm == null) {
+ Log.e(TAG, "Ignored connect request for " + storedDevice
+ + " : no state machine");
+ continue;
+ }
+ sm.sendMessage(LeAudioStateMachine.CONNECT);
+ }
+ }
+
+ }
+
// Suppressed since this is part of a local process
@SuppressLint("AndroidFrameworkRequiresPermission")
void messageFromNative(LeAudioStackEvent stackEvent) {
@@ -905,6 +917,8 @@
case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
sm = getOrCreateStateMachine(device);
+ /* Incoming connection try to connect other devices from the group */
+ connectSet(device);
break;
default:
break;
@@ -976,6 +990,7 @@
} else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED) {
int group_id = stackEvent.valueInt1;
int group_status = stackEvent.valueInt2;
+ boolean send_intent = false;
switch (group_status) {
case LeAudioStackEvent.GROUP_STATUS_ACTIVE: {
@@ -985,6 +1000,7 @@
descriptor.mIsActive = true;
updateActiveDevices(group_id, ACTIVE_CONTEXTS_NONE,
descriptor.mActiveContexts, descriptor.mIsActive);
+ send_intent = true;
}
} else {
Log.e(TAG, "no descriptors for group: " + group_id);
@@ -998,6 +1014,7 @@
descriptor.mIsActive = false;
updateActiveDevices(group_id, descriptor.mActiveContexts,
ACTIVE_CONTEXTS_NONE, descriptor.mIsActive);
+ send_intent = true;
}
} else {
Log.e(TAG, "no descriptors for group: " + group_id);
@@ -1008,10 +1025,11 @@
break;
}
- intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_GROUP_STATUS_CHANGED);
- intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_GROUP_ID, group_id);
- intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_GROUP_STATUS, group_status);
-
+ if (send_intent) {
+ intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_GROUP_STATUS_CHANGED);
+ intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_GROUP_ID, group_id);
+ intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_GROUP_STATUS, group_status);
+ }
}
if (intent != null) {
diff --git a/src/com/android/bluetooth/mapclient/OWNERS b/src/com/android/bluetooth/mapclient/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/src/com/android/bluetooth/mapclient/OWNERS
+++ b/src/com/android/bluetooth/mapclient/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/src/com/android/bluetooth/pbapclient/OWNERS b/src/com/android/bluetooth/pbapclient/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/src/com/android/bluetooth/pbapclient/OWNERS
+++ b/src/com/android/bluetooth/pbapclient/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/src/com/android/bluetooth/vc/VolumeControlService.java b/src/com/android/bluetooth/vc/VolumeControlService.java
index cb22e4d..b47a0ff 100644
--- a/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -260,7 +260,7 @@
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
- List<BluetoothDevice> getConnectedDevices() {
+ public List<BluetoothDevice> getConnectedDevices() {
enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
"Need BLUETOOTH_PRIVILEGED permission");
synchronized (mStateMachines) {
diff --git a/tests/OWNERS b/tests/OWNERS
index 06dc3f8..fd47bd7 100644
--- a/tests/OWNERS
+++ b/tests/OWNERS
@@ -1 +1 @@
-include platform/system/bt:/OWNERS_automotive
+include platform/packages/modules/Bluetooth:/OWNERS_automotive
diff --git a/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
index 71843c5..ef26da1 100644
--- a/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
+++ b/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
@@ -97,6 +97,7 @@
private @Mock Binder mBinder;
private @Mock AudioManager mAudioManager;
private @Mock android.app.Application mApplication;
+ private @Mock MetricsLogger mMockMetricsLogger;
// BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the
// underlying binder calls.
@@ -215,6 +216,10 @@
when(mMockService.getName()).thenReturn("Service1");
when(mMockService2.getName()).thenReturn("Service2");
+ when(mMockMetricsLogger.init(any())).thenReturn(true);
+ when(mMockMetricsLogger.close()).thenReturn(true);
+ mAdapterService.setMetricsLogger(mMockMetricsLogger);
+
// Attach a context to the service for permission checks.
mAdapterService.attach(mMockContext, null, null, null, mApplication, null);
mAdapterService.onCreate();
diff --git a/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java b/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
index cc4e8b7..235a25c 100644
--- a/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
+++ b/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
@@ -15,9 +15,13 @@
*/
package com.android.bluetooth.btservice;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog;
import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats;
import com.android.bluetooth.BluetoothMetricsProto.ProfileId;
@@ -27,6 +31,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.HashMap;
import java.util.List;
@@ -37,17 +43,42 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
public class MetricsLoggerTest {
+ private TestableMetricsLogger mTestableMetricsLogger;
+ @Mock
+ private AdapterService mMockAdapterService;
+
+ public class TestableMetricsLogger extends MetricsLogger {
+ public HashMap<Integer, Long> mTestableCounters = new HashMap<>();
+
+ @Override
+ protected void writeCounter(int key, long count) {
+ mTestableCounters.put(key, count);
+ }
+
+ @Override
+ protected void scheduleDrains() {
+ }
+
+ @Override
+ protected void cancelPendingDrain() {
+ }
+ }
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
// Dump metrics to clean up internal states
MetricsLogger.dumpProto(BluetoothLog.newBuilder());
+ mTestableMetricsLogger = new TestableMetricsLogger();
+ doReturn(null)
+ .when(mMockAdapterService).registerReceiver(any(), any());
}
@After
public void tearDown() {
// Dump metrics to clean up internal states
MetricsLogger.dumpProto(BluetoothLog.newBuilder());
+ mTestableMetricsLogger.close();
}
/**
@@ -104,4 +135,75 @@
return profileUsageStatsMap;
}
-}
+ /**
+ * Test add counters and send them to westworld
+ */
+ @Test
+ public void testAddAndSendCountersNormalCases() {
+ mTestableMetricsLogger.init(mMockAdapterService);
+ mTestableMetricsLogger.count(1, 10);
+ mTestableMetricsLogger.count(1, 10);
+ mTestableMetricsLogger.count(2, 5);
+ mTestableMetricsLogger.drainBufferedCounters();
+
+ Assert.assertEquals(20L, mTestableMetricsLogger.mTestableCounters.get(1).longValue());
+ Assert.assertEquals(5L, mTestableMetricsLogger.mTestableCounters.get(2).longValue());
+
+ mTestableMetricsLogger.count(1, 3);
+ mTestableMetricsLogger.count(2, 5);
+ mTestableMetricsLogger.count(2, 5);
+ mTestableMetricsLogger.count(3, 1);
+ mTestableMetricsLogger.drainBufferedCounters();
+ Assert.assertEquals(
+ 3L, mTestableMetricsLogger.mTestableCounters.get(1).longValue());
+ Assert.assertEquals(
+ 10L, mTestableMetricsLogger.mTestableCounters.get(2).longValue());
+ Assert.assertEquals(
+ 1L, mTestableMetricsLogger.mTestableCounters.get(3).longValue());
+ }
+
+ @Test
+ public void testAddAndSendCountersCornerCases() {
+ mTestableMetricsLogger.init(mMockAdapterService);
+ Assert.assertTrue(mTestableMetricsLogger.isInitialized());
+ mTestableMetricsLogger.count(1, -1);
+ mTestableMetricsLogger.count(3, 0);
+ mTestableMetricsLogger.count(2, 10);
+ mTestableMetricsLogger.count(2, Long.MAX_VALUE - 8L);
+ mTestableMetricsLogger.drainBufferedCounters();
+
+ Assert.assertFalse(mTestableMetricsLogger.mTestableCounters.containsKey(1));
+ Assert.assertFalse(mTestableMetricsLogger.mTestableCounters.containsKey(3));
+ Assert.assertEquals(
+ Long.MAX_VALUE, mTestableMetricsLogger.mTestableCounters.get(2).longValue());
+ }
+
+ @Test
+ public void testMetricsLoggerClose() {
+ mTestableMetricsLogger.init(mMockAdapterService);
+ mTestableMetricsLogger.count(1, 1);
+ mTestableMetricsLogger.count(2, 10);
+ mTestableMetricsLogger.count(2, Long.MAX_VALUE);
+ mTestableMetricsLogger.close();
+
+ Assert.assertEquals(
+ 1, mTestableMetricsLogger.mTestableCounters.get(1).longValue());
+ Assert.assertEquals(
+ Long.MAX_VALUE, mTestableMetricsLogger.mTestableCounters.get(2).longValue());
+ }
+
+ @Test
+ public void testMetricsLoggerNotInit() {
+ Assert.assertFalse(mTestableMetricsLogger.count(1, 1));
+ mTestableMetricsLogger.drainBufferedCounters();
+ Assert.assertFalse(mTestableMetricsLogger.mTestableCounters.containsKey(1));
+ Assert.assertFalse(mTestableMetricsLogger.close());
+ }
+
+ @Test
+ public void testAddAndSendCountersDoubleInit() {
+ Assert.assertTrue(mTestableMetricsLogger.init(mMockAdapterService));
+ Assert.assertTrue(mTestableMetricsLogger.isInitialized());
+ Assert.assertFalse(mTestableMetricsLogger.init(mMockAdapterService));
+ }
+}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java b/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java
index 99a9f34..130f457 100644
--- a/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java
+++ b/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java
@@ -137,9 +137,9 @@
public void testListenForPhoneState_ServiceAndSignalStrength() {
BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
}
/**
@@ -150,9 +150,9 @@
public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffSignalStrengh() {
BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE));
@@ -165,9 +165,9 @@
public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffAll() {
BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
}
@@ -183,12 +183,12 @@
BluetoothDevice device2 = TestUtils.getTestDevice(mAdapter, 2);
// Enabling updates from first device should trigger subscription
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
// Enabling updates from second device should not trigger the same subscription
mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
// Disabling updates from first device should not cancel subscription
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
// Disabling updates from second device should cancel subscription
@@ -211,15 +211,15 @@
verifyNoMoreInteractions(mTelephonyManager);
// Partially enabling updates from second device should trigger partial subscription
mHeadsetPhoneState.listenForPhoneState(device2,
- PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
// Partially disabling updates from first device should not cancel all subscription
mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
verify(mTelephonyManager).listen(
- any(), eq(PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH));
+ any(), eq(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
// Partially disabling updates from second device should cancel subscription
mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_NONE);
verify(mTelephonyManager, times(3)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
diff --git a/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java b/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
index 7ff5f1c..3ebcc05 100644
--- a/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
+++ b/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
@@ -954,8 +954,7 @@
mHeadsetService.startVoiceRecognition(deviceA);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseCode(deviceA,
HeadsetHalConstants.AT_RESPONSE_OK, 0);
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connectAudio(deviceA);
verifyNoMoreInteractions(mNativeInterface);
}
@@ -1008,8 +1007,7 @@
// We still continue on the initiating HF
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseCode(deviceA,
HeadsetHalConstants.AT_RESPONSE_OK, 0);
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connectAudio(deviceA);
verifyNoMoreInteractions(mNativeInterface);
}
@@ -1084,8 +1082,7 @@
verify(mNativeInterface).setActiveDevice(deviceA);
Assert.assertEquals(deviceA, mHeadsetService.getActiveDevice());
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).startVoiceRecognition(deviceA);
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connectAudio(deviceA);
waitAndVerifyAudioStateIntent(ASYNC_CALL_TIMEOUT_MILLIS, deviceA,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
@@ -1133,8 +1130,7 @@
Assert.assertTrue(mHeadsetService.startVoiceRecognition(device));
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).atResponseCode(device,
HeadsetHalConstants.AT_RESPONSE_OK, 0);
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connectAudio(device);
waitAndVerifyAudioStateIntent(ASYNC_CALL_TIMEOUT_MILLIS, device,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
@@ -1151,8 +1147,7 @@
Assert.assertNotNull(device);
Assert.assertTrue(mHeadsetService.startVoiceRecognition(device));
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).startVoiceRecognition(device);
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connectAudio(device);
waitAndVerifyAudioStateIntent(ASYNC_CALL_TIMEOUT_MILLIS, device,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
diff --git a/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java b/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java
index 1a4e877..d1888bb 100644
--- a/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java
+++ b/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java
@@ -706,7 +706,7 @@
headsetCallState.mType, headsetCallState.mName, mAdapter.getAttributionSource());
TestUtils.waitForLooperToFinishScheduledTask(
mHeadsetService.getStateMachinesThreadLooper());
- verify(mAudioManager, never()).setParameters("A2dpSuspended=true");
+ verify(mAudioManager, never()).setA2dpSuspended(true);
HeadsetTestUtils.verifyPhoneStateChangeSetters(mPhoneState, headsetCallState,
ASYNC_CALL_TIMEOUT_MILLIS);
}
@@ -765,7 +765,7 @@
mHeadsetService.getStateMachinesThreadLooper());
// Should not ask Audio HAL to suspend A2DP without active device
- verify(mAudioManager, never()).setParameters("A2dpSuspended=true");
+ verify(mAudioManager, never()).setA2dpSuspended(true);
// Make sure we notify device about this change
verify(mStateMachines.get(mCurrentDevice)).sendMessage(
HeadsetStateMachine.CALL_STATE_CHANGED, headsetCallState);
@@ -783,7 +783,7 @@
TestUtils.waitForLooperToFinishScheduledTask(
mHeadsetService.getStateMachinesThreadLooper());
// Ask Audio HAL to suspend A2DP
- verify(mAudioManager).setParameters("A2dpSuspended=true");
+ verify(mAudioManager).setA2dpSuspended(true);
// Make sure state is updated
verify(mStateMachines.get(mCurrentDevice)).sendMessage(
HeadsetStateMachine.CALL_STATE_CHANGED, headsetCallState);
@@ -847,8 +847,7 @@
headsetCallState.mNumHeld, headsetCallState.mCallState, headsetCallState.mNumber,
headsetCallState.mType, headsetCallState.mName, mAdapter.getAttributionSource());
// Ask Audio HAL to suspend A2DP
- verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS))
- .setParameters("A2dpSuspended=true");
+ verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setA2dpSuspended(true);
// Make sure we notify devices about this change
for (BluetoothDevice device : connectedDevices) {
verify(mStateMachines.get(device)).sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED,
diff --git a/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
index fde7dd6..f927a61 100644
--- a/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
+++ b/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
@@ -896,7 +896,7 @@
public void testAtBiaEvent_initialSubscriptionWithUpdates() {
setUpConnectedState();
verify(mPhoneState).listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(true, true, false, false), mTestDevice));
@@ -906,7 +906,7 @@
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(false, true, true, false), mTestDevice));
verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice,
- PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH);
+ PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(false, true, false, false), mTestDevice));