summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
author William Escande <wescande@google.com> 2025-03-10 15:16:21 -0700
committer William Escande <wescande@google.com> 2025-03-12 18:52:18 -0700
commit793282209b26d676d00e7d38dd7b84396c2b3782 (patch)
tree270d46fdfdb37bd477a4f5668efba4ff787916d3 /service
parentfb610bad48bab1bbfea676a93fa5ea9ab30070a4 (diff)
Clean system server threads
Bug: 402209603 Flag: com.android.bluetooth.flags.system_server_remove_extra_thread_jump Test: atest ServiceBluetoothTests Change-Id: Ic73976f7bfd92da873c95412ba0fa0181b112c85
Diffstat (limited to 'service')
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java193
-rw-r--r--service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java129
2 files changed, 240 insertions, 82 deletions
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 3f1017f88d..5f13b6266a 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -138,10 +138,17 @@ class BluetoothManagerService {
// Delay for retrying enable and disable in msec
@VisibleForTesting static final int ENABLE_DISABLE_DELAY_MS = 300 * HW_MULTIPLIER;
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_ENABLE = 1;
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_DISABLE = 2;
+
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
+
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
+
@VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
@VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
@VisibleForTesting static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
@@ -325,8 +332,9 @@ class BluetoothManagerService {
} else if (state != STATE_ON && state != STATE_OFF && state != STATE_BLE_ON) {
// Bluetooth is turning state
return ADD_PROXY_DELAY_MS;
- } else if (mHandler.hasMessages(MESSAGE_ENABLE)
- || mHandler.hasMessages(MESSAGE_DISABLE)
+ } else if ((!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_ENABLE)
+ || mHandler.hasMessages(MESSAGE_DISABLE)))
|| mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)
|| mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
|| mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE)
@@ -1036,6 +1044,42 @@ class BluetoothManagerService {
return true;
}
+ private static CompletableFuture<Void> createDeathNotifier(IBinder binder) {
+ CompletableFuture<Void> deathNotifier = new CompletableFuture<>();
+ try {
+ binder.linkToDeath(
+ () -> {
+ Log.i(TAG, "Successfully received Bluetooth death");
+ deathNotifier.complete(null);
+ },
+ 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "listenBinderDeath(): Failed to linkToDeath", e);
+ deathNotifier.complete(null);
+ }
+ return deathNotifier;
+ }
+
+ private static void killBluetoothProcess(
+ AdapterBinder adapter, CompletableFuture<Void> deathNotifier) {
+ try {
+ // Force kill Bluetooth to make sure its process is not reused.
+ // Note: In a perfect world, we should be able to re-init the same process.
+ // Unfortunately, this requires an heavy rework of the Bluetooth app
+ // TODO: b/339501753 - Properly stop Bluetooth without killing it
+ adapter.killBluetoothProcess();
+
+ deathNotifier.get(2_000, TimeUnit.MILLISECONDS);
+ } catch (android.os.DeadObjectException e) {
+ // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
+ Log.i(TAG, "killBluetoothProcess(): Bluetooth already dead 💀");
+ } catch (RemoteException e) {
+ Log.e(TAG, "killBluetoothProcess(): Unable to call killBluetoothProcess", e);
+ } catch (TimeoutException | InterruptedException | ExecutionException e) {
+ Log.e(TAG, "killBluetoothProcess(): Bluetooth death not received after > 2000ms", e);
+ }
+ }
+
void unbindAndFinish() {
Log.d(TAG, "unbindAndFinish(): mAdapter=" + mAdapter + " isBinding=" + isBinding());
@@ -1052,40 +1096,13 @@ class BluetoothManagerService {
Log.e(TAG, "unbindAndFinish(): Unable to unregister BluetoothCallback", e);
}
- CompletableFuture<Void> binderDead = new CompletableFuture<>();
- try {
- mAdapter.getAdapterBinder()
- .asBinder()
- .linkToDeath(
- () -> {
- Log.i(TAG, "Successfully received Bluetooth death");
- binderDead.complete(null);
- },
- 0);
- } catch (RemoteException e) {
- Log.e(TAG, "unbindAndFinish(): Failed to linkToDeath", e);
- binderDead.complete(null);
- }
+ CompletableFuture<Void> deathNotifier =
+ createDeathNotifier(mAdapter.getAdapterBinder().asBinder());
// Unbind first to avoid receiving unwanted "onServiceDisconnected"
mContext.unbindService(mConnection);
- try {
- // Force kill Bluetooth to make sure its process is not reused.
- // Note: In a perfect world, we should be able to re-init the same process.
- // Unfortunately, this requires an heavy rework of the Bluetooth app
- // TODO: b/339501753 - Properly stop Bluetooth without killing it
- mAdapter.killBluetoothProcess();
-
- binderDead.get(2_000, TimeUnit.MILLISECONDS);
- } catch (android.os.DeadObjectException e) {
- // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
- Log.i(TAG, "unbindAndFinish(): Bluetooth already dead 💀");
- } catch (RemoteException e) {
- Log.e(TAG, "unbindAndFinish(): Unable to call killBluetoothProcess", e);
- } catch (TimeoutException | InterruptedException | ExecutionException e) {
- Log.e(TAG, "unbindAndFinish(): Bluetooth death not received after > 2000ms", e);
- }
+ killBluetoothProcess(mAdapter, deathNotifier);
long timeSpentForShutdown = System.currentTimeMillis() - currentTimeMs;
mShutdownLatencyHistogram.logSample((float) timeSpentForShutdown);
@@ -1250,8 +1267,12 @@ class BluetoothManagerService {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE:
- int quietEnable = msg.arg1;
- int isBle = msg.arg2;
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ break;
+ }
+
+ boolean quietEnable = msg.arg1 != 0;
+ boolean isBle = msg.arg2 != 0;
Log.d(
TAG,
@@ -1263,6 +1284,10 @@ class BluetoothManagerService {
break;
case MESSAGE_DISABLE:
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ break;
+ }
+
Log.d(TAG, "MESSAGE_DISABLE: mAdapter=" + mAdapter);
handleDisableMessage();
@@ -1309,6 +1334,15 @@ class BluetoothManagerService {
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
IBinder service = (IBinder) msg.obj;
+
+ // Handle case where disable was called before binding complete.
+ if (Flags.systemServerRemoveExtraThreadJump() && !isBinding() && !mEnable) {
+ Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: after cancelling binding");
+ AdapterBinder adapter =
+ BluetoothServerProxy.getInstance().createAdapterBinder(service);
+ killBluetoothProcess(adapter, createDeathNotifier(service));
+ break;
+ }
Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: service=" + service);
// Remove timeout
@@ -1328,7 +1362,7 @@ class BluetoothManagerService {
offToBleOn();
sendBluetoothServiceUpCallback();
- if (!mEnable) {
+ if (!Flags.systemServerRemoveExtraThreadJump() && !mEnable) {
waitForState(STATE_ON);
onToBleOn();
}
@@ -1361,7 +1395,9 @@ class BluetoothManagerService {
if (prevState == STATE_BLE_TURNING_OFF && newState == STATE_OFF) {
if (mEnable) {
Log.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
- waitForState(STATE_OFF);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ waitForState(STATE_OFF);
+ }
mHandler.sendEmptyMessageDelayed(
MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
}
@@ -1522,17 +1558,19 @@ class BluetoothManagerService {
return mHandler.hasMessages(MESSAGE_TIMEOUT_BIND);
}
- private void handleEnableMessage(int quietEnable, int isBle) {
+ private void handleEnableMessage(boolean quietEnable, boolean isBle) {
+ String logHeader = "handleEnableMessage(" + quietEnable + ", " + isBle + "): ";
if (mShutdownInProgress) {
- Log.d(TAG, "Skip Bluetooth Enable in device shutdown process");
+ Log.d(TAG, logHeader + "Skip Bluetooth Enable in device shutdown process");
return;
}
- if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
- || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ if (!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED))) {
// We are handling enable or disable right now, wait for it.
mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_ENABLE, quietEnable, isBle),
+ mHandler.obtainMessage(MESSAGE_ENABLE, quietEnable ? 1 : 0, isBle ? 1 : 0),
ENABLE_DISABLE_DELAY_MS);
return;
}
@@ -1540,27 +1578,27 @@ class BluetoothManagerService {
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
- if (isBle == 0) {
+ if (!isBle) {
setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
}
if (mState.oneOf(STATE_BLE_TURNING_ON, STATE_TURNING_ON, STATE_ON)) {
- Log.i(TAG, "MESSAGE_ENABLE: already enabled. Current state=" + mState);
+ Log.i(TAG, logHeader + "Already enabled. Current state=" + mState);
return;
}
- if (mState.oneOf(STATE_BLE_ON) && isBle == 1) {
- Log.i(TAG, "MESSAGE_ENABLE: Already in BLE_ON while being requested to go to BLE_ON");
+ if (mState.oneOf(STATE_BLE_ON) && isBle) {
+ Log.i(TAG, logHeader + "Already in BLE_ON while being requested to go to BLE_ON");
return;
}
if (mState.oneOf(STATE_BLE_ON)) {
- Log.i(TAG, "MESSAGE_ENABLE: Bluetooth transition from STATE_BLE_ON to STATE_ON");
+ Log.i(TAG, logHeader + "Bluetooth transition from STATE_BLE_ON to STATE_ON");
bleOnToOn();
return;
}
- if (mAdapter != null) {
+ if (!Flags.systemServerRemoveExtraThreadJump() && mAdapter != null) {
// TODO: b/339548431 - Adapt this after removal of Flags.explicitKillFromSystemServer
//
// We need to wait until transitioned to STATE_OFF and the previous Bluetooth process
@@ -1579,14 +1617,15 @@ class BluetoothManagerService {
return;
}
- mQuietEnable = (quietEnable == 1);
+ mQuietEnable = quietEnable;
handleEnable();
}
private void handleDisableMessage() {
- if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
- || isBinding()
- || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ if (!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+ || isBinding()
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED))) {
// We are handling enable or disable right now, wait for it.
mHandler.sendEmptyMessageDelayed(MESSAGE_DISABLE, ENABLE_DISABLE_DELAY_MS);
return;
@@ -1594,10 +1633,25 @@ class BluetoothManagerService {
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- if (mEnable && mAdapter != null) {
+ if (Flags.systemServerRemoveExtraThreadJump() && isBinding()) {
+ Log.d(TAG, "Disable while binding");
+ mEnable = false;
+ mContext.unbindService(mConnection);
+ mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
+ } else if (Flags.systemServerRemoveExtraThreadJump()
+ && mState.oneOf(STATE_BLE_TURNING_ON)) {
+ Log.d(TAG, "Disable while BLE_TURNING_ON");
+ mEnable = false;
+ bluetoothStateChangeHandler(STATE_BLE_TURNING_ON, STATE_OFF);
+ } else if (mEnable && mAdapter != null) {
mWaitForDisableRetry = 0;
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleDisableDelayed(false);
+ } else {
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ }
} else {
mEnable = false;
onToBleOn();
@@ -1646,6 +1700,10 @@ class BluetoothManagerService {
Log.e(TAG, "Wait for STATE_OFF timeout");
}
}
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleEnable();
+ return;
+ }
// Either state is changed to STATE_OFF or reaches the maximum retry, we
// should move forward to the next step.
mWaitForEnableRetry = 0;
@@ -1654,6 +1712,9 @@ class BluetoothManagerService {
}
private void handleDisableDelayed(boolean disabling) {
+ if (Flags.systemServerRemoveExtraThreadJump() && disabling) {
+ return;
+ }
if (!disabling) {
// The Bluetooth is turning on, wait for STATE_ON
if (!mState.oneOf(STATE_ON)) {
@@ -1671,10 +1732,12 @@ class BluetoothManagerService {
mWaitForDisableRetry = 0;
mEnable = false;
onToBleOn();
- // Wait for state exiting STATE_ON
- Message disableDelayedMsg =
- mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
- mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ // Wait for state exiting STATE_ON
+ Message disableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ }
} else {
// The Bluetooth is turning off, wait for exiting STATE_ON
if (mState.oneOf(STATE_ON)) {
@@ -1835,8 +1898,13 @@ class BluetoothManagerService {
}
private void sendDisableMsg(int reason, String packageName) {
- mHandler.sendEmptyMessage(MESSAGE_DISABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mHandler.sendEmptyMessage(MESSAGE_DISABLE);
+ }
ActiveLogs.add(reason, false, packageName, false);
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleDisableMessage();
+ }
}
private void sendEnableMsg(boolean quietMode, int reason) {
@@ -1848,9 +1916,14 @@ class BluetoothManagerService {
}
private void sendEnableMsg(boolean quietMode, int reason, String packageName, boolean isBle) {
- mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, isBle ? 1 : 0).sendToTarget();
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, isBle ? 1 : 0).sendToTarget();
+ }
ActiveLogs.add(reason, true, packageName, isBle);
mLastEnabledTime = SystemClock.elapsedRealtime();
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleEnableMessage(quietMode, isBle);
+ }
}
private void addCrashLog() {
diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
index c6105ec731..5e2b66ac06 100644
--- a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
+++ b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
@@ -36,6 +36,7 @@ import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_RESTO
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_TIMEOUT_BIND;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
@@ -69,12 +70,16 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.test.TestLooper;
import android.permission.PermissionManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bluetooth.flags.Flags;
+
import org.hamcrest.Matcher;
import org.hamcrest.core.AllOf;
import org.junit.After;
@@ -102,7 +107,8 @@ public class BluetoothManagerServiceTest {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf();
+ return FlagsParameterization.allCombinationsOf(
+ Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP);
}
public BluetoothManagerServiceTest(FlagsParameterization flags) {
@@ -258,9 +264,13 @@ public class BluetoothManagerServiceTest {
IntStream.of(what)
.forEach(
w -> {
+ String log = "Expecting message " + w + ": ";
+
Message msg = mLooper.nextMessage();
- assertThat(msg).isNotNull();
- assertThat(msg.what).isEqualTo(w);
+ assertWithMessage(log + "but got null").that(msg).isNotNull();
+ assertWithMessage(log + "but got " + msg.what)
+ .that(msg.what)
+ .isEqualTo(w);
msg.getTarget().dispatchMessage(msg);
});
}
@@ -295,7 +305,9 @@ public class BluetoothManagerServiceTest {
// called from SYSTEM user, should try to toggle Bluetooth off
mManagerService.onUserRestrictionsChanged(UserHandle.SYSTEM);
- syncHandler(MESSAGE_DISABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_DISABLE);
+ }
}
@Test
@@ -308,7 +320,9 @@ public class BluetoothManagerServiceTest {
anyInt(),
any(UserHandle.class));
mManagerService.enableBle("enable_bindFailure_removesTimeout", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
verify(mContext).unbindService(any());
mInOrder.verify(mContext).unbindService(any());
@@ -320,7 +334,9 @@ public class BluetoothManagerServiceTest {
@Test
public void enable_bindTimeout() throws Exception {
mManagerService.enableBle("enable_bindTimeout", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
mLooper.moveTimeForward(120_000); // 120 seconds
syncHandler(MESSAGE_TIMEOUT_BIND);
@@ -414,7 +430,9 @@ public class BluetoothManagerServiceTest {
@Test
public void enable_whileTurningToBleOn_shouldEnable() throws Exception {
mManagerService.enableBle("enable_whileTurningToBleOn_shouldEnable", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
acceptBluetoothBinding();
IBluetoothCallback btCallback = captureBluetoothCallback();
@@ -422,7 +440,9 @@ public class BluetoothManagerServiceTest {
// receive enable when Bluetooth is in BLE_TURNING_ON
mManagerService.enable("enable_whileTurningToBleOn_shouldEnable");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
btCallback.onBluetoothStateChange(STATE_BLE_TURNING_ON, STATE_BLE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
@@ -433,12 +453,16 @@ public class BluetoothManagerServiceTest {
@Test
public void enable_whileNotYetBoundToBle_shouldEnable() throws Exception {
mManagerService.enableBle("enable_whileTurningToBleOn_shouldEnable", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
// receive enable when Bluetooth is OFF and not yet binded
mManagerService.enable("enable_whileTurningToBleOn_shouldEnable");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
acceptBluetoothBinding();
IBluetoothCallback btCallback = captureBluetoothCallback();
@@ -453,7 +477,9 @@ public class BluetoothManagerServiceTest {
@Test
public void offToBleOn() throws Exception {
mManagerService.enableBle("test_offToBleOn", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
transition_offToBleOn();
@@ -465,7 +491,9 @@ public class BluetoothManagerServiceTest {
@Test
public void offToOn() throws Exception {
mManagerService.enable("test_offToOn");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
transition_offToOn();
@@ -475,7 +503,9 @@ public class BluetoothManagerServiceTest {
@Test
public void crash_whileTransitionState_canRecover() throws Exception {
mManagerService.enableBle("crash_whileTransitionState_canRecover", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
BluetoothManagerService.BluetoothServiceConnection serviceConnection =
acceptBluetoothBinding();
@@ -504,28 +534,83 @@ public class BluetoothManagerServiceTest {
@Test
public void disableAirplane_whenNothing_startBluetooth() throws Exception {
- mPersistedState = BluetoothManagerService.BLUETOOTH_ON_BLUETOOTH;
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mPersistedState = BluetoothManagerService.BLUETOOTH_ON_BLUETOOTH;
+ }
mManagerService.enable("disableAirplane_whenNothing_startBluetooth");
- discardMessage(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ discardMessage(MESSAGE_ENABLE);
+ } else {
+ transition_offToOn();
+ }
+
+ assertThat(mLooper.nextMessage()).isNull();
mManagerService.onAirplaneModeChanged(false);
- discardMessage(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ discardMessage(MESSAGE_ENABLE);
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenBinding_bluetoothShouldStop_new() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_new");
+ mInOrder.verify(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_new", true);
+ mInOrder.verify(mContext).unbindService(any());
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenTurningBleOn_bluetoothShouldStop() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_new");
+ acceptBluetoothBinding();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_new", true);
+ mInOrder.verify(mContext).unbindService(any());
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenBinding_bluetoothShouldStop_old() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_old");
+ syncHandler(MESSAGE_ENABLE);
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_old", true);
+ syncHandler(MESSAGE_DISABLE);
+
+ IBluetoothCallback btCallback = transition_offToBleOn();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_OFF);
+
+ btCallback.onBluetoothStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
+ syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_DISABLE);
+
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
}
@Test
public void disableAirplane_whenFactoryReset_doesNotStartBluetooth() throws Exception {
mManagerService.enable("disableAirplane_whenFactoryReset_doesNotStartBluetooth");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
IBluetoothCallback btCallback = transition_offToOn();
assertThat(mManagerService.getState()).isEqualTo(STATE_ON);
mManagerService.mHandler.sendEmptyMessage(MESSAGE_RESTORE_USER_SETTING_OFF);
syncHandler(MESSAGE_RESTORE_USER_SETTING_OFF);
- syncHandler(MESSAGE_DISABLE);
- mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
- syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
- mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
- syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_DISABLE);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ }
transition_onToOff(btCallback);
mManagerService.onAirplaneModeChanged(false);