summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabián Kozynski <kozynski@google.com> 2023-10-11 11:11:27 -0400
committer Fabián Kozynski <kozynski@google.com> 2023-10-11 11:13:59 -0400
commit764a626d297f94df28b1067a5afe791a5eac985c (patch)
treef2af6881348ec002a9931773d1cbcbd1b72a2318
parent721668de97aee4ffbaf6ff6aa07cf49b5ed08fe8 (diff)
Move updateAudioProfile work to bg
updateAudioProfile makes calls to determine state of CachedBluetoothDevice. Those calls need to happe in the background. As this is called from the callback in updateConnected (which ends up being called in main thread), we need to send this off thread. Also, add annotations on methods we know should be called from a bg thread. Test: atest BluetoothControllerImplTest Test: perfetto trace (no calls in main thread after continuation) Fixes: 304103830 Fixes: 289430339 Change-Id: Ie1cdbdf63ea6731c553c827fcdbfb8bef340c400
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepository.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java12
3 files changed, 47 insertions, 22 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 945cc6bc2519..53b343c09329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -27,6 +27,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.NonNull;
+import androidx.annotation.WorkerThread;
import com.android.internal.annotations.GuardedBy;
import com.android.settingslib.bluetooth.BluetoothCallback;
@@ -36,6 +37,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.bluetooth.BluetoothLogger;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.UserTracker;
@@ -81,6 +83,8 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
private int mState;
private final BluetoothAdapter mAdapter;
+
+ private final Executor mBackgroundExecutor;
/**
*/
@Inject
@@ -90,6 +94,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
DumpManager dumpManager,
BluetoothLogger logger,
BluetoothRepository bluetoothRepository,
+ @Background Executor executor,
@Main Looper mainLooper,
@Nullable LocalBluetoothManager localBluetoothManager,
@Nullable BluetoothAdapter bluetoothAdapter) {
@@ -98,6 +103,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
mBluetoothRepository = bluetoothRepository;
mLocalBluetoothManager = localBluetoothManager;
mHandler = new H(mainLooper);
+ mBackgroundExecutor = executor;
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().registerCallback(this);
mLocalBluetoothManager.getProfileManager().addServiceListener(this);
@@ -218,6 +224,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
return mIsActive;
}
+ @WorkerThread
@Override
public void setBluetoothEnabled(boolean enabled) {
if (mLocalBluetoothManager != null) {
@@ -230,6 +237,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
return mLocalBluetoothManager != null;
}
+ @WorkerThread
@Override
public String getConnectedDeviceName() {
synchronized (mConnectedDevices) {
@@ -251,6 +259,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
getDevices(), this::onConnectionStatusFetched);
}
+ // Careful! This may be invoked in the main thread.
private void onConnectionStatusFetched(ConnectionStatusModel status) {
List<CachedBluetoothDevice> newList = status.getConnectedDevices();
int state = status.getMaxConnectionState();
@@ -282,30 +291,33 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
private void updateAudioProfile() {
- boolean audioProfileConnected = false;
- boolean otherProfileConnected = false;
-
- for (CachedBluetoothDevice device : getDevices()) {
- for (LocalBluetoothProfile profile : device.getProfiles()) {
- int profileId = profile.getProfileId();
- boolean isConnected = device.isConnectedProfile(profile);
- if (profileId == BluetoothProfile.HEADSET
- || profileId == BluetoothProfile.A2DP
- || profileId == BluetoothProfile.HEARING_AID
- || profileId == BluetoothProfile.LE_AUDIO) {
- audioProfileConnected |= isConnected;
- } else {
- otherProfileConnected |= isConnected;
+ // We want this in the background as calls inside `LocalBluetoothProfile` end up being
+ // binder calls
+ mBackgroundExecutor.execute(() -> {
+ boolean audioProfileConnected = false;
+ boolean otherProfileConnected = false;
+
+ for (CachedBluetoothDevice device : getDevices()) {
+ for (LocalBluetoothProfile profile : device.getProfiles()) {
+ int profileId = profile.getProfileId();
+ boolean isConnected = device.isConnectedProfile(profile);
+ if (profileId == BluetoothProfile.HEADSET
+ || profileId == BluetoothProfile.A2DP
+ || profileId == BluetoothProfile.HEARING_AID
+ || profileId == BluetoothProfile.LE_AUDIO) {
+ audioProfileConnected |= isConnected;
+ } else {
+ otherProfileConnected |= isConnected;
+ }
}
}
- }
-
- boolean audioProfileOnly = (audioProfileConnected && !otherProfileConnected);
- if (audioProfileOnly != mAudioProfileOnly) {
- mAudioProfileOnly = audioProfileOnly;
- mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
- }
+ boolean audioProfileOnly = (audioProfileConnected && !otherProfileConnected);
+ if (audioProfileOnly != mAudioProfileOnly) {
+ mAudioProfileOnly = audioProfileOnly;
+ mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
+ }
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepository.kt
index 80f3d76f0897..96717c7542d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepository.kt
@@ -38,7 +38,8 @@ interface BluetoothRepository {
/**
* Fetches the connection statuses for the given [currentDevices] and invokes [callback] once
* those statuses have been fetched. The fetching occurs on a background thread because IPCs may
- * be required to fetch the statuses (see b/271058380).
+ * be required to fetch the statuses (see b/271058380). However, the callback will be invoked in
+ * the main thread.
*/
fun fetchConnectionStatusInBackground(
currentDevices: Collection<CachedBluetoothDevice>,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index e76163575738..a1da16737aa4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -75,6 +75,8 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
private BluetoothAdapter mMockAdapter;
private List<CachedBluetoothDevice> mDevices;
+ private FakeExecutor mBackgroundExecutor;
+
@Before
public void setup() throws Exception {
mTestableLooper = TestableLooper.get(this);
@@ -91,6 +93,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
when(mMockBluetoothManager.getProfileManager())
.thenReturn(mock(LocalBluetoothProfileManager.class));
mMockDumpManager = mock(DumpManager.class);
+ mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
BluetoothRepository bluetoothRepository =
new FakeBluetoothRepository(mMockBluetoothManager);
@@ -101,6 +104,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
mMockDumpManager,
mock(BluetoothLogger.class),
bluetoothRepository,
+ mBackgroundExecutor,
mTestableLooper.getLooper(),
mMockBluetoothManager,
mMockAdapter);
@@ -205,6 +209,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
mBluetoothControllerImpl.onAclConnectionStateChanged(device,
BluetoothProfile.STATE_CONNECTED);
mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.HEADSET);
+ mBackgroundExecutor.runAllReady();
assertTrue(mBluetoothControllerImpl.isBluetoothAudioActive());
assertTrue(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
@@ -290,6 +295,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ false);
mBluetoothControllerImpl.onDeviceAdded(device);
+ mBackgroundExecutor.runAllReady();
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
}
@@ -300,6 +306,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
BluetoothProfile.HEADSET, /* isConnected= */ true, /* isActive= */ false);
mBluetoothControllerImpl.onDeviceAdded(device);
+ mBackgroundExecutor.runAllReady();
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
}
@@ -310,6 +317,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
BluetoothProfile.A2DP, /* isConnected= */ true, /* isActive= */ false);
mBluetoothControllerImpl.onDeviceAdded(device);
+ mBackgroundExecutor.runAllReady();
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
}
@@ -320,6 +328,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
BluetoothProfile.HEARING_AID, /* isConnected= */ true, /* isActive= */ false);
mBluetoothControllerImpl.onDeviceAdded(device);
+ mBackgroundExecutor.runAllReady();
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
}
@@ -337,6 +346,8 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
mBluetoothControllerImpl.onDeviceAdded(device2);
mBluetoothControllerImpl.onDeviceAdded(device3);
+ mBackgroundExecutor.runAllReady();
+
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
}
@@ -349,6 +360,7 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
mBluetoothControllerImpl.onDeviceAdded(device1);
mBluetoothControllerImpl.onDeviceAdded(device2);
+ mBackgroundExecutor.runAllReady();
assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isFalse();
}