Merge "[Temp bonding] Updater for the guest list to store temp bond device" into main

This commit is contained in:
Ze Li
2025-01-16 23:20:21 -08:00
committed by Android (Google) Code Review
2 changed files with 213 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2025 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.connecteddevice.audiosharing;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.flags.Flags;
/** Maintain and update connected temporary bond bluetooth devices */
public class TemporaryBondDeviceGroupUpdater extends BluetoothDeviceUpdater {
private static final String TAG = "TemporaryBondDeviceGroupUpdater";
private static final String PREF_KEY_PREFIX = "temp_bond_bt_";
public TemporaryBondDeviceGroupUpdater(
@NonNull Context context,
@NonNull DevicePreferenceCallback devicePreferenceCallback,
int metricsCategory) {
super(context, devicePreferenceCallback, metricsCategory);
}
@Override
public boolean isFilterMatched(@NonNull CachedBluetoothDevice cachedDevice) {
// Only connected temporary bond device should be shown in this section when Audio
// sharing UI is available.
boolean isFilterMatched = Flags.enableTemporaryBondDevicesUi()
&& BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice())
&& isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)
&& BluetoothUtils.isAudioSharingUIAvailable(mContext);
Log.d(
TAG,
"isFilterMatched() device : "
+ cachedDevice.getName()
+ ", isFilterMatched : "
+ isFilterMatched);
return isFilterMatched;
}
@Override
protected String getPreferenceKeyPrefix() {
return PREF_KEY_PREFIX;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected void update(CachedBluetoothDevice cachedBluetoothDevice) {
super.update(cachedBluetoothDevice);
Log.d(TAG, "Map : " + mPreferenceMap);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2025 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.connecteddevice.audiosharing;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.flags.Flags;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.Collection;
/** Tests for {@link TemporaryBondDeviceGroupUpdater}. */
@RunWith(RobolectricTestRunner.class)
@Config(
shadows = {
ShadowBluetoothAdapter.class,
ShadowBluetoothUtils.class
})
public class TemporaryBondDeviceGroupUpdaterTest {
private static final String TAG = "TemporaryBondDeviceGroupUpdater";
private static final String PREF_KEY_PREFIX = "temp_bond_bt_";
private static final String TEMP_BOND_METADATA =
"<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private DevicePreferenceCallback mDevicePreferenceCallback;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private BluetoothDevice mBluetoothDevice;
@Mock
private LocalBluetoothManager mLocalBtManager;
@Mock
private CachedBluetoothDeviceManager mCachedDeviceManager;
private TemporaryBondDeviceGroupUpdater mDeviceUpdater;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(
BluetoothAdapter.getDefaultAdapter());
shadowBluetoothAdapter.setEnabled(true);
shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
Context context = ApplicationProvider.getApplicationContext();
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
mLocalBtManager = Utils.getLocalBtManager(context);
when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
cachedDevices.add(mCachedBluetoothDevice);
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
mDeviceUpdater =
spy(
new TemporaryBondDeviceGroupUpdater(
context, mDevicePreferenceCallback, /* metricsCategory= */ 0));
mDeviceUpdater.setPrefContext(context);
}
@After
public void tearDown() {
ShadowBluetoothUtils.reset();
}
@Test
@RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI,
Flags.FLAG_ENABLE_LE_AUDIO_SHARING})
public void isFilterMatched_isTemporaryBondDevice_returnsTrue() {
when(mBluetoothDevice.isConnected()).thenReturn(true);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
.thenReturn(TEMP_BOND_METADATA.getBytes());
assertThat(mDeviceUpdater.isFilterMatched(mCachedBluetoothDevice)).isTrue();
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mDeviceUpdater.getLogTag()).isEqualTo(TAG);
}
@Test
public void getPreferenceKey_returnsCorrectKey() {
assertThat(mDeviceUpdater.getPreferenceKeyPrefix()).isEqualTo(PREF_KEY_PREFIX);
}
}