Merge "[LE Audio] To remove the broadcast source item that created by receive state"
diff --git a/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreference.java b/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreference.java
index 733a4a9..9904e8b 100644
--- a/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreference.java
@@ -171,6 +171,16 @@
}
/**
+ * Whether the broadcast source is connected at the beginging. We will get the
+ * BluetoothLeBroadcastReceiveState from the broadcast source.
+ * See {@link BluetoothFindBroadcastsFragment#addConnectedSourcePreference}
+ * @return If true, the broadcast source is already connected by the broadcast sink.
+ */
+ public boolean isCreatedByReceiveState() {
+ return mBluetoothLeBroadcastReceiveState != null;
+ }
+
+ /**
* Clear the BluetoothLeBroadcastReceiveState and reset the state when the user clicks the
* "leave broadcast" button.
*/
diff --git a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
index 13388b3..e08a244 100644
--- a/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragment.java
@@ -37,7 +37,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import com.android.settings.R;
@@ -75,9 +74,11 @@
CachedBluetoothDevice mCachedDevice;
@VisibleForTesting
PreferenceCategory mBroadcastSourceListCategory;
+ @VisibleForTesting
+ BluetoothBroadcastSourcePreference mSelectedPreference;
BluetoothFindBroadcastsHeaderController mBluetoothFindBroadcastsHeaderController;
+
private LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
- private BluetoothBroadcastSourcePreference mSelectedPreference;
private Executor mExecutor;
private int mSourceId;
@@ -369,19 +370,31 @@
return pref;
}
- private void addSource(BluetoothBroadcastSourcePreference pref) {
+ @VisibleForTesting
+ void addSource(BluetoothBroadcastSourcePreference pref) {
if (mLeBroadcastAssistant == null || mCachedDevice == null) {
Log.w(TAG, "addSource: LeBroadcastAssistant or CachedDevice is null!");
return;
}
if (mSelectedPreference != null) {
- // The previous preference status set false after user selects the new Preference.
- getActivity().runOnUiThread(
+ if (mSelectedPreference.isCreatedByReceiveState()) {
+ Log.d(TAG, "addSource: Remove preference that created by getAllSources()");
+ getActivity().runOnUiThread(() ->
+ mBroadcastSourceListCategory.removePreference(mSelectedPreference));
+ if (mLeBroadcastAssistant != null && !mLeBroadcastAssistant.isSearchInProgress()) {
+ Log.d(TAG, "addSource: Start Searching For Broadcast Sources");
+ mLeBroadcastAssistant.startSearchingForSources(getScanFilter());
+ }
+ } else {
+ Log.d(TAG, "addSource: Update preference that created by onSourceFound()");
+ // The previous preference status set false after user selects the new Preference.
+ getActivity().runOnUiThread(
() -> {
mSelectedPreference.updateMetadataAndRefreshUi(
mSelectedPreference.getBluetoothLeBroadcastMetadata(), false);
mSelectedPreference.setOrder(1);
});
+ }
}
mSelectedPreference = pref;
mLeBroadcastAssistant.addSource(mCachedDevice.getDevice(),
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreferenceTest.java
new file mode 100644
index 0000000..85d12b9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothBroadcastSourcePreferenceTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.bluetooth.BluetoothLeBroadcastReceiveState;
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothBroadcastSourcePreferenceTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
+ @Mock
+ BluetoothLeBroadcastMetadata mBroadcastMetadata;
+
+ BluetoothBroadcastSourcePreference mPreference;
+
+
+ @Before
+ public void setUp() {
+ mPreference = new BluetoothBroadcastSourcePreference(mContext);
+ }
+
+ @Test
+ public void isCreatedByReceiveState_updateUiFromReceviceState_returnsTrue() {
+ mPreference.updateReceiveStateAndRefreshUi(mBroadcastReceiveState);
+
+ assertThat(mPreference.isCreatedByReceiveState()).isTrue();
+ }
+
+ @Test
+ public void isCreatedByReceiveState_updateUiFromMetadata_returnsFalse() {
+ mPreference.updateMetadataAndRefreshUi(mBroadcastMetadata, true);
+
+ assertThat(mPreference.isCreatedByReceiveState()).isFalse();
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragmentTest.java
new file mode 100644
index 0000000..9551c9a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothFindBroadcastsFragmentTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+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.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.PreferenceCategory;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class BluetoothFindBroadcastsFragmentTest {
+
+ private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
+
+ private BluetoothFindBroadcastsFragment mFragment;
+ private FragmentActivity mActivity;
+ private Context mContext;
+ private FragmentTransaction mFragmentTransaction;
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private CachedBluetoothDevice mCachedDevice;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private LocalBluetoothManager mLocalManager;
+ @Mock
+ private PreferenceCategory mPreferenceCategroy;
+ @Mock
+ private LocalBluetoothLeBroadcastAssistant mBroadcastAssistant;
+ @Mock
+ private BluetoothLeBroadcastMetadata mBroadcastMetadata;
+ @Mock
+ private BluetoothBroadcastSourcePreference mBroadcastSourcePreference;
+ @Mock
+ private BluetoothBroadcastSourcePreference mBroadcastSourcePreferenceUserClick;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ FakeFeatureFactory.setupForTest();
+
+ mFragment = spy(new BluetoothFindBroadcastsFragment());
+ doReturn(mLocalManager).when(mFragment).getLocalBluetoothManager(any());
+ doReturn(mCachedDevice).when(mFragment).getCachedDevice(any());
+ doReturn(mBroadcastAssistant).when(mFragment).getLeBroadcastAssistant();
+ doReturn(mPreferenceCategroy).when(mFragment).findPreference(any());
+ mActivity = Robolectric.setupActivity(FragmentActivity.class);
+ when(mFragment.getActivity()).thenReturn(mActivity);
+
+ FragmentManager fragmentManager = mock(FragmentManager.class);
+ when(mFragment.getFragmentManager()).thenReturn(fragmentManager);
+ mFragmentTransaction = mock(FragmentTransaction.class);
+ when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
+
+ when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
+ when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS);
+ Bundle args = new Bundle();
+ args.putString(BluetoothFindBroadcastsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
+ mFragment.setArguments(args);
+ mFragment.onAttach(mContext);
+ }
+
+ @Test
+ public void verifyOnAttachResult() {
+ assertThat(mFragment.mDeviceAddress).isEqualTo(TEST_ADDRESS);
+ assertThat(mFragment.mManager).isEqualTo(mLocalManager);
+ assertThat(mFragment.mCachedDevice).isEqualTo(mCachedDevice);
+ }
+
+ @Test
+ public void addSource_selectedPrefIsNull_returnsNewPref() {
+ mFragment.mSelectedPreference = null;
+
+ mFragment.addSource(mBroadcastSourcePreference);
+
+ assertThat(mFragment.mSelectedPreference).isEqualTo(mBroadcastSourcePreference);
+ }
+
+ @Test
+ public void addSource_sourcePrefIsCreatedByReceiveState_removesOldPref() {
+ mFragment.mSelectedPreference = mBroadcastSourcePreference;
+ mFragment.mBroadcastSourceListCategory = mPreferenceCategroy;
+ doReturn(true).when(mFragment.mSelectedPreference).isCreatedByReceiveState();
+
+ mFragment.addSource(mBroadcastSourcePreferenceUserClick);
+
+ verify(mFragment.mBroadcastSourceListCategory).removePreference(mBroadcastSourcePreference);
+ assertThat(mFragment.mSelectedPreference).isEqualTo(mBroadcastSourcePreferenceUserClick);
+ }
+
+ @Test
+ public void addSource_sourcePrefIsCreatedByMetadata_updatesOldPref() {
+ when(mBroadcastSourcePreference.isCreatedByReceiveState()).thenReturn(false);
+ when(mBroadcastSourcePreference.getBluetoothLeBroadcastMetadata())
+ .thenReturn(mBroadcastMetadata);
+ mFragment.mSelectedPreference = mBroadcastSourcePreference;
+ mFragment.mBroadcastSourceListCategory = mPreferenceCategroy;
+
+ mFragment.addSource(mBroadcastSourcePreferenceUserClick);
+
+ verify(mBroadcastSourcePreference).updateMetadataAndRefreshUi(
+ any(BluetoothLeBroadcastMetadata.class), anyBoolean());
+ assertThat(mFragment.mSelectedPreference).isEqualTo(mBroadcastSourcePreferenceUserClick);
+ }
+
+}