[Audiosharing] add profile service listener when BT just on

If receive BT on while profile service not ready, add profile service
listener and do things, e.g. update preference, when all relative
profile services connected.

Test: atest
Bug: 305620450
Flag: com.android.settingslib.flags.enable_le_audio_sharing
Change-Id: Ie56ed70190285785f1750a7cbbb16029b566fcbe
This commit is contained in:
Yiyi Shen
2025-01-23 15:33:06 +08:00
parent a618a8a241
commit e9b6016b8d
4 changed files with 147 additions and 39 deletions

View File

@@ -136,8 +136,17 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateSwitch();
mListener.onAudioSharingStateChanged();
if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
== BluetoothAdapter.STATE_ON
&& !AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
if (mProfileManager != null) {
mProfileManager.addServiceListener(
AudioSharingSwitchBarController.this);
}
} else {
updateSwitch();
mListener.onAudioSharingStateChanged();
}
}
};
@@ -360,14 +369,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
}
mContext.registerReceiver(mReceiver, mIntentFilter, Context.RECEIVER_EXPORTED_UNAUDITED);
updateSwitch();
registerCallbacks();
if (!AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
if (mProfileManager != null) {
mProfileManager.addServiceListener(this);
}
Log.d(TAG, "Skip register callbacks. Profile is not ready.");
Log.d(TAG, "Skip handleStartAudioSharingFromIntent. Profile is not ready.");
return;
}
registerCallbacks();
if (mIntentHandleStage.compareAndSet(
StartIntentHandleStage.TO_HANDLE.ordinal(),
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal())) {
@@ -445,7 +454,6 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
public void onServiceConnected() {
Log.d(TAG, "onServiceConnected()");
if (AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
registerCallbacks();
updateSwitch();
mListener.onAudioSharingProfilesConnected();
mListener.onAudioSharingStateChanged();
@@ -525,7 +533,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
}
private void unregisterCallbacks() {
if (!isAvailable() || !AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
if (!isAvailable()) {
Log.d(TAG, "Skip unregisterCallbacks(). Feature is not available.");
return;
}

View File

@@ -52,7 +52,15 @@ public class StreamSettingsCategoryController extends BasePreferenceController
@Override
public void onReceive(Context context, Intent intent) {
if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) return;
updateVisibility();
if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
== BluetoothAdapter.STATE_ON && !isProfileReady()) {
if (mProfileManager != null) {
mProfileManager.addServiceListener(
StreamSettingsCategoryController.this);
}
} else {
updateVisibility();
}
}
};
@@ -97,7 +105,7 @@ public class StreamSettingsCategoryController extends BasePreferenceController
@Override
public void onServiceConnected() {
if (isAvailable() && isProfileReady()) {
if (isProfileReady()) {
updateVisibility();
if (mProfileManager != null) {
mProfileManager.removeServiceListener(this);

View File

@@ -51,6 +51,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Looper;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.FeatureFlagUtils;
import android.util.Pair;
@@ -244,8 +246,53 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void bluetoothOn_profileReady_switchEnabled() {
mSwitchBar.setEnabled(false);
mContext.registerReceiver(
mController.mReceiver,
mController.mIntentFilter,
Context.RECEIVER_EXPORTED_UNAUDITED);
mShadowBluetoothAdapter.setEnabled(true);
when(mBroadcast.isEnabled(null)).thenReturn(false);
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
mContext.sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle();
verify(mSwitchBar).setEnabled(true);
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mOnAudioSharingStateChanged).isTrue();
assertThat(mOnAudioSharingServiceConnected).isFalse();
verify(mBtProfileManager, never()).addServiceListener(any());
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void bluetoothOn_profileNotReady_switchDisabled_registerProfileListener() {
mSwitchBar.setEnabled(false);
mContext.registerReceiver(
mController.mReceiver,
mController.mIntentFilter,
Context.RECEIVER_EXPORTED_UNAUDITED);
mShadowBluetoothAdapter.setEnabled(true);
when(mBroadcast.isEnabled(null)).thenReturn(false);
when(mBroadcast.isProfileReady()).thenReturn(false);
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
mContext.sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mSwitchBar.isEnabled()).isFalse();
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mOnAudioSharingStateChanged).isFalse();
assertThat(mOnAudioSharingServiceConnected).isFalse();
verify(mBtProfileManager).addServiceListener(mController);
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void bluetoothOff_switchDisabled() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
assertThat(mSwitchBar.isEnabled()).isTrue();
mContext.registerReceiver(
mController.mReceiver,
@@ -262,11 +309,12 @@ public class AudioSharingSwitchBarControllerTest {
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mOnAudioSharingStateChanged).isTrue();
assertThat(mOnAudioSharingServiceConnected).isFalse();
verify(mBtProfileManager, never()).addServiceListener(any());
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onServiceConnected_switchEnabled() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isEnabled(null)).thenReturn(true);
mController.onServiceConnected();
shadowOf(Looper.getMainLooper()).idle();
@@ -279,20 +327,20 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void getAvailabilityStatus_flagOn() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void getAvailabilityStatus_flagOff() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOff_doNothing() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStart(mLifecycleOwner);
verify(mContext, never())
.registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
@@ -306,8 +354,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOnProfileNotReady_registerProfileCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isEnabled(null)).thenReturn(false);
when(mBroadcast.isProfileReady()).thenReturn(false);
mController.onStart(mLifecycleOwner);
@@ -315,21 +363,21 @@ public class AudioSharingSwitchBarControllerTest {
verify(mContext)
.registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
verify(mBroadcast, never())
verify(mBroadcast)
.registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcast.Callback.class));
verify(mAssistant, never())
verify(mAssistant)
.registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class));
verify(mEventManager).registerCallback(any(BluetoothCallback.class));
verify(mBtProfileManager).addServiceListener(mController);
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mSwitchBar.isEnabled()).isFalse();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOn_registerCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isEnabled(null)).thenReturn(true);
mController.onStart(mLifecycleOwner);
shadowOf(Looper.getMainLooper()).idle();
@@ -349,8 +397,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOn_updateSwitch() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isEnabled(null)).thenReturn(false);
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
mController.onStart(mLifecycleOwner);
@@ -361,8 +409,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStop_flagOff_doNothing() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStop(mLifecycleOwner);
verify(mContext, never()).unregisterReceiver(any(BroadcastReceiver.class));
verify(mBroadcast, never())
@@ -374,8 +422,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStop_flagOn_notRegistered_doNothing() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.setCallbacksRegistered(false);
doNothing().when(mContext).unregisterReceiver(any(BroadcastReceiver.class));
mController.onStop(mLifecycleOwner);
@@ -390,8 +438,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStop_flagOn_registered_unregisterCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.setCallbacksRegistered(true);
mContext.registerReceiver(
mController.mReceiver,
@@ -956,8 +1004,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void handleStartAudioSharingFromIntent_flagOff_doNothing() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
var unused = setUpFragmentWithStartSharingIntent();
mController.onStart(mLifecycleOwner);
shadowOf(Looper.getMainLooper()).idle();
@@ -966,8 +1014,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void handleStartAudioSharingFromIntent_profileNotReady_doNothing() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mAssistant.isProfileReady()).thenReturn(false);
var unused = setUpFragmentWithStartSharingIntent();
mController.onServiceConnected();
@@ -977,8 +1025,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void handleStartAudioSharingFromIntent_argFalse_doNothing() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStart(mLifecycleOwner);
shadowOf(Looper.getMainLooper()).idle();
@@ -986,8 +1034,8 @@ public class AudioSharingSwitchBarControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void handleStartAudioSharingFromIntent_handle() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBtnView.isEnabled()).thenReturn(true);
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);

View File

@@ -36,6 +36,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Looper;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.lifecycle.LifecycleOwner;
@@ -124,8 +126,50 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
public void bluetoothOff_updateVisibility() {
public void bluetoothOn_profileReady_updateVisibility() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mShadowBluetoothAdapter.setEnabled(false);
mContext.registerReceiver(
mController.mReceiver,
mController.mIntentFilter,
Context.RECEIVER_EXPORTED_UNAUDITED);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.isVisible()).isFalse();
mShadowBluetoothAdapter.setEnabled(true);
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
mContext.sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.isVisible()).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void bluetoothOn_profileNotReady_registerProfileListener() {
mShadowBluetoothAdapter.setEnabled(false);
mContext.registerReceiver(
mController.mReceiver,
mController.mIntentFilter,
Context.RECEIVER_EXPORTED_UNAUDITED);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.isVisible()).isFalse();
when(mBroadcast.isProfileReady()).thenReturn(false);
mShadowBluetoothAdapter.setEnabled(true);
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
mContext.sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mPreference.isVisible()).isFalse();
verify(mBtProfileManager).addServiceListener(mController);
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void bluetoothOff_updateVisibility() {
mContext.registerReceiver(
mController.mReceiver,
mController.mIntentFilter,
@@ -143,20 +187,20 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void getAvailabilityStatus_flagOn() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void getAvailabilityStatus_flagOff() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOff_doNothing() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStart(mLifecycleOwner);
verify(mContext, times(0))
.registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
@@ -164,8 +208,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOn_registerCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStart(mLifecycleOwner);
verify(mContext)
.registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
@@ -173,8 +217,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStart_flagOnProfileNotReady_registerProfileManagerCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isProfileReady()).thenReturn(false);
mController.onStart(mLifecycleOwner);
verify(mContext)
@@ -183,16 +227,16 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStop_flagOff_doNothing() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mController.onStop(mLifecycleOwner);
verify(mContext, times(0)).unregisterReceiver(any(BroadcastReceiver.class));
verify(mBtProfileManager, times(0)).removeServiceListener(mController);
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onStop_flagOn_unregisterCallback() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
doNothing().when(mContext).unregisterReceiver(any(BroadcastReceiver.class));
mController.onStop(mLifecycleOwner);
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
@@ -200,8 +244,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void displayPreference_flagOff_preferenceInvisible() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mPreference.setVisible(true);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
@@ -209,8 +253,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void displayPreference_BluetoothOff_preferenceInvisible() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mPreference.setVisible(true);
mShadowBluetoothAdapter.setEnabled(false);
mController.displayPreference(mScreen);
@@ -219,8 +263,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void displayPreference_BluetoothOnProfileNotReady_preferenceInvisible() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mPreference.setVisible(true);
when(mBroadcast.isProfileReady()).thenReturn(false);
mController.displayPreference(mScreen);
@@ -229,8 +273,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void displayPreference_BluetoothOnProfileReady_preferenceVisible() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mPreference.setVisible(false);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();
@@ -238,8 +282,8 @@ public class StreamSettingsCategoryControllerTest {
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void onServiceConnected_updateVisibility() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mBroadcast.isProfileReady()).thenReturn(false);
mController.displayPreference(mScreen);
shadowOf(Looper.getMainLooper()).idle();