Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf5646c9 authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge "[Audiosharing] Refresh preference when onServiceConnected" into main

parents 69829e93 0e786c01
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -37,19 +37,22 @@ import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.utils.ThreadUtils;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AudioSharingPreferenceController extends BasePreferenceController
        implements DefaultLifecycleObserver, BluetoothCallback {
        implements DefaultLifecycleObserver, BluetoothCallback,
        LocalBluetoothProfileManager.ServiceListener {
    private static final String TAG = "AudioSharingPreferenceController";
    private static final String CONNECTED_DEVICES_PREF_KEY =
            "connected_device_audio_sharing_settings";
    private static final String CONNECTION_PREFERENCES_PREF_KEY = "audio_sharing_settings";

    @Nullable private final LocalBluetoothManager mBtManager;
    @Nullable private final LocalBluetoothProfileManager mProfileManager;
    @Nullable private final BluetoothEventManager mEventManager;
    @Nullable private final LocalBluetoothLeBroadcast mBroadcast;
    @Nullable private Preference mPreference;
@@ -94,11 +97,9 @@ public class AudioSharingPreferenceController extends BasePreferenceController
    public AudioSharingPreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);
        mBtManager = Utils.getLocalBtManager(context);
        mProfileManager = mBtManager == null ? null : mBtManager.getProfileManager();
        mEventManager = mBtManager == null ? null : mBtManager.getEventManager();
        mBroadcast =
                mBtManager == null
                        ? null
                        : mBtManager.getProfileManager().getLeAudioBroadcastProfile();
        mBroadcast = mProfileManager == null ? null : mProfileManager.getLeAudioBroadcastProfile();
        mExecutor = Executors.newSingleThreadExecutor();
    }

@@ -114,6 +115,13 @@ public class AudioSharingPreferenceController extends BasePreferenceController
        }
        mEventManager.registerCallback(this);
        mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
        if (!AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
            if (mProfileManager != null) {
                mProfileManager.addServiceListener(this);
            }
            Log.d(TAG, "Skip updateVisibility. Profile is not ready.");
            return;
        }
        updateVisibility();
    }

@@ -129,6 +137,9 @@ public class AudioSharingPreferenceController extends BasePreferenceController
        }
        mEventManager.unregisterCallback(this);
        mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
        if (mProfileManager != null) {
            mProfileManager.removeServiceListener(this);
        }
    }

    @Override
@@ -141,7 +152,6 @@ public class AudioSharingPreferenceController extends BasePreferenceController
        if (mPreference != null && CONNECTED_DEVICES_PREF_KEY.equals(getPreferenceKey())) {
            mPreference.setVisible(false);
        }
        updateVisibility();
    }

    @Override
@@ -150,6 +160,20 @@ public class AudioSharingPreferenceController extends BasePreferenceController
                : UNSUPPORTED_ON_DEVICE;
    }

    @Override
    public void onServiceConnected() {
        if (AudioSharingUtils.isAudioSharingProfileReady(mProfileManager)) {
            Log.d(TAG, "onServiceConnected, audio sharing ready");
            refreshPreference();
            if (mProfileManager != null) {
                mProfileManager.removeServiceListener(this);
            }
        }
    }

    @Override
    public void onServiceDisconnected() {}

    @Override
    public CharSequence getSummary() {
        return switch (getPreferenceKey()) {
+86 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -39,6 +40,8 @@ import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
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;
@@ -52,9 +55,12 @@ import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.VolumeControlProfile;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.flags.Flags;

@@ -122,8 +128,8 @@ public class AudioSharingPreferenceControllerTest {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStart_flagOn_registerCallback() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        setupControllerWithKey(PREF_KEY1);
        mController.onStart(mLifecycleOwner);
        verify(mBtEventManager).registerCallback(mController);
@@ -131,8 +137,8 @@ public class AudioSharingPreferenceControllerTest {
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStart_flagOff_skipRegisterCallback() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        setupControllerWithKey(PREF_KEY1);
        mController.onStart(mLifecycleOwner);
        verify(mBtEventManager, never()).registerCallback(mController);
@@ -141,8 +147,8 @@ public class AudioSharingPreferenceControllerTest {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStop_flagOn_unregisterCallback() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        setupControllerWithKey(PREF_KEY1);
        mController.onStop(mLifecycleOwner);
        verify(mBtEventManager).unregisterCallback(mController);
@@ -150,8 +156,8 @@ public class AudioSharingPreferenceControllerTest {
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStop_flagOff_skipUnregisterCallback() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        setupControllerWithKey(PREF_KEY1);
        mController.onStop(mLifecycleOwner);
        verify(mBtEventManager, never()).unregisterCallback(mController);
@@ -160,15 +166,15 @@ public class AudioSharingPreferenceControllerTest {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void getAvailabilityStatus_flagOn() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        setupControllerWithKey(PREF_KEY1);
        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);
        setupControllerWithKey(PREF_KEY1);
        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
    }
@@ -203,6 +209,59 @@ public class AudioSharingPreferenceControllerTest {
        assertThat(mController.getSummary().toString()).isEmpty();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStart_profilesReady_refreshVisibility() {
        setupControllerWithKey(PREF_KEY2);
        setAudioSharingProfilesReady(true);
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        mController.displayPreference(mScreen);
        shadowOf(Looper.getMainLooper()).idle();
        mController.onStart(mLifecycleOwner);
        shadowOf(Looper.getMainLooper()).idle();
        verify(mPreference, never()).setSummary(any());
        assertThat(mPreference.isVisible()).isTrue();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
    public void onStart_profilesNotReady_notRefreshVisibility() {
        setupControllerWithKey(PREF_KEY2);
        setAudioSharingProfilesReady(false);
        mController.displayPreference(mScreen);
        mController.onStart(mLifecycleOwner);
        shadowOf(Looper.getMainLooper()).idle();
        verify(mPreference, never()).setSummary(any());
        assertThat(mPreference.isVisible()).isFalse();
        verify(mLocalBtProfileManager).addServiceListener(mController);
    }

    @Test
    public void onServiceConnected_profilesReady_refreshSummary() {
        setupControllerWithKey(PREF_KEY1);
        setAudioSharingProfilesReady(true);
        mController.displayPreference(mScreen);
        mController.onServiceConnected();
        shadowOf(Looper.getMainLooper()).idle();
        assertThat(mPreference.getSummary().toString())
                .isEqualTo(mContext.getString(R.string.audio_sharing_summary_off));
        assertThat(mPreference.isVisible()).isTrue();
        verify(mLocalBtProfileManager).removeServiceListener(mController);
    }

    @Test
    public void onServiceConnected_profilesReady_refreshVisibility() {
        setupControllerWithKey(PREF_KEY2);
        setAudioSharingProfilesReady(true);
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        mController.displayPreference(mScreen);
        mController.onServiceConnected();
        shadowOf(Looper.getMainLooper()).idle();
        verify(mPreference, never()).setSummary(any());
        assertThat(mPreference.isVisible()).isTrue();
        verify(mLocalBtProfileManager).removeServiceListener(mController);
    }

    @Test
    public void onBluetoothStateChanged_refreshSummary() {
        setupControllerWithKey(PREF_KEY1);
@@ -324,7 +383,7 @@ public class AudioSharingPreferenceControllerTest {
        setupControllerWithKey(PREF_KEY2);
        mController.displayPreference(mScreen);
        shadowOf(Looper.getMainLooper()).idle();
        verify(mPreference, times(3)).setVisible(anyBoolean());
        verify(mPreference, times(2)).setVisible(anyBoolean());

        mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
        verify(mPreference, never()).setSummary(any());
@@ -341,7 +400,7 @@ public class AudioSharingPreferenceControllerTest {
        mController.mBroadcastCallback.onBroadcastUpdateFailed(
                /* reason= */ 1, /* broadcastId= */ 1);
        verify(mPreference, never()).setSummary(any());
        verify(mPreference, times(3)).setVisible(anyBoolean());
        verify(mPreference, times(2)).setVisible(anyBoolean());
    }

    private void setupControllerWithKey(String preferenceKey) {
@@ -349,4 +408,23 @@ public class AudioSharingPreferenceControllerTest {
        mPreference = spy(new Preference(mContext));
        when(mScreen.findPreference(preferenceKey)).thenReturn(mPreference);
    }

    private void setAudioSharingProfilesReady(boolean ready) {
        if (ready) {
            when(mBroadcast.isProfileReady()).thenReturn(true);
            LocalBluetoothLeBroadcastAssistant assistant = mock(
                    LocalBluetoothLeBroadcastAssistant.class);
            LeAudioProfile lea = mock(LeAudioProfile.class);
            VolumeControlProfile vc = mock(VolumeControlProfile.class);
            when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(
                    assistant);
            when(mLocalBtProfileManager.getLeAudioProfile()).thenReturn(lea);
            when(mLocalBtProfileManager.getVolumeControlProfile()).thenReturn(vc);
            when(assistant.isProfileReady()).thenReturn(true);
            when(lea.isProfileReady()).thenReturn(true);
            when(vc.isProfileReady()).thenReturn(true);
        } else {
            when(mBroadcast.isProfileReady()).thenReturn(false);
        }
    }
}