Merge changes from topic "exclusive-manager" into main
* changes:
[Hide DCK devices] Hide DCK devices from settings app (other devices section).
[Hide DCK devices] Hide DCK devices from settings app (saved devices page).
diff --git a/aconfig/settings_connecteddevice_flag_declarations.aconfig b/aconfig/settings_connecteddevice_flag_declarations.aconfig
index 5ba2129..0fc164e 100644
--- a/aconfig/settings_connecteddevice_flag_declarations.aconfig
+++ b/aconfig/settings_connecteddevice_flag_declarations.aconfig
@@ -33,4 +33,11 @@
namespace: "pixel_cross_device_control"
description: "Order the saved bluetooth devices by most recently connected."
bug: "306160434"
+}
+
+flag {
+ name: "enable_hide_exclusively_managed_bluetooth_device"
+ namespace: "dck_framework"
+ description: "Hide exclusively managed Bluetooth devices in BT settings menu."
+ bug: "322285078"
}
\ No newline at end of file
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index 489c095..012220c 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -24,6 +24,8 @@
import androidx.preference.Preference;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.flags.Flags;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
/**
@@ -95,6 +97,15 @@
cachedDevice.getName() + ", isFilterMatched : " + isFilterMatched);
}
}
+ if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
+ if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
+ cachedDevice.getDevice())) {
+ if (DBG) {
+ Log.d(TAG, "isFilterMatched() hide BluetoothDevice with exclusive manager");
+ }
+ return false;
+ }
+ }
return isFilterMatched;
}
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index bfd4221..1db90fa 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -25,6 +25,8 @@
import androidx.preference.Preference;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.flags.Flags;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -99,12 +101,22 @@
@Override
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
final BluetoothDevice device = cachedDevice.getDevice();
- Log.d(TAG, "isFilterMatched() device name : " + cachedDevice.getName() +
- ", is connected : " + device.isConnected() + ", is profile connected : "
- + cachedDevice.isConnected());
- return device.getBondState() == BluetoothDevice.BOND_BONDED
- && (mShowConnectedDevice || (!device.isConnected() && isDeviceInCachedDevicesList(
- cachedDevice)));
+ boolean isExclusivelyManaged = BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
+ cachedDevice.getDevice());
+ Log.d(TAG, "isFilterMatched() device name : " + cachedDevice.getName()
+ + ", is connected : " + device.isConnected() + ", is profile connected : "
+ + cachedDevice.isConnected() + ", is exclusively managed : "
+ + isExclusivelyManaged);
+ if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
+ return device.getBondState() == BluetoothDevice.BOND_BONDED
+ && (mShowConnectedDevice || (!device.isConnected()
+ && isDeviceInCachedDevicesList(cachedDevice)))
+ && !isExclusivelyManaged;
+ } else {
+ return device.getBondState() == BluetoothDevice.BOND_BONDED
+ && (mShowConnectedDevice || (!device.isConnected()
+ && isDeviceInCachedDevicesList(cachedDevice)));
+ }
}
@Override
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
index 00115d7..cd48bf1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
@@ -20,6 +20,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,18 +30,26 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Pair;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
import com.android.settings.testutils.shadow.ShadowAudioManager;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowCachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -58,6 +68,10 @@
public class ConnectedBluetoothDeviceUpdaterTest {
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
+ private static final String FAKE_EXCLUSIVE_MANAGER_NAME = "com.fake.name";
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private DashboardFragment mDashboardFragment;
@@ -69,6 +83,8 @@
private BluetoothDevice mBluetoothDevice;
@Mock
private Drawable mDrawable;
+ @Mock
+ private PackageManager mPackageManager;
private Context mContext;
private ConnectedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -82,7 +98,7 @@
MockitoAnnotations.initMocks(this);
Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
mAudioManager = mContext.getSystemService(AudioManager.class);
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
mShadowBluetoothAdapter.setEnabled(true);
@@ -92,6 +108,7 @@
mCachedDevices = new ArrayList<>();
mCachedDevices.add(mCachedBluetoothDevice);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
@@ -320,4 +337,97 @@
assertThat(btPreference.shouldHideSecondTarget()).isTrue();
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_notExclusiveManagedDevice_addDevice() {
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ null);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_notAllowedExclusiveManagedDevice_addDevice() {
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ FAKE_EXCLUSIVE_MANAGER_NAME.getBytes());
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_existingExclusivelyManagedDeviceWithPackageInstalled_removePreference()
+ throws Exception {
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+ doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_newExclusivelyManagedDeviceWithPackageInstalled_doNotAddPreference()
+ throws Exception {
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+ doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_exclusivelyManagedDeviceWithoutPackageInstalled_addDevice()
+ throws Exception {
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+ doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getPackageInfo(
+ exclusiveManagerName, 0);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
index c229449..349391d 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -28,17 +29,26 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Pair;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -56,6 +66,10 @@
public class SavedBluetoothDeviceUpdaterTest {
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
+ private static final String FAKE_EXCLUSIVE_MANAGER_NAME = "com.fake.name";
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private DashboardFragment mDashboardFragment;
@@ -73,6 +87,8 @@
private LocalBluetoothManager mBluetoothManager;
@Mock
private Drawable mDrawable;
+ @Mock
+ private PackageManager mPackageManager;
private Context mContext;
private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -84,12 +100,13 @@
MockitoAnnotations.initMocks(this);
Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
doReturn(mContext).when(mDashboardFragment).getContext();
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext,
mDevicePreferenceCallback, false, /* metricsCategory= */ 0));
@@ -103,10 +120,10 @@
mCachedDevices.add(mCachedBluetoothDevice);
when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
-
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
public void update_filterMatch_addPreference() {
doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState();
doReturn(false).when(mBluetoothDevice).isConnected();
@@ -118,6 +135,7 @@
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
public void update_filterNotMatch_removePreference() {
doReturn(BluetoothDevice.BOND_NONE).when(mBluetoothDevice).getBondState();
doReturn(true).when(mBluetoothDevice).isConnected();
@@ -298,4 +316,125 @@
verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
BluetoothDevicePreference.SortType.TYPE_NO_SORT);
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_notExclusivelyManagedDevice_addDevice() {
+ final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ cachedDevices.add(mCachedBluetoothDevice);
+
+ when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ null);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_notAllowedExclusivelyManagedDevice_addDevice() {
+ final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ cachedDevices.add(mCachedBluetoothDevice);
+
+ when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ FAKE_EXCLUSIVE_MANAGER_NAME.getBytes());
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_existingExclusivelyManagedDeviceWithPackageInstalled_removePreference()
+ throws Exception {
+ final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+
+ when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+
+ doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+ mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_newExclusivelyManagedDeviceWithPackageInstalled_doNotAddPreference()
+ throws Exception {
+ final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+ cachedDevices.add(mCachedBluetoothDevice);
+
+ when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+
+ doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+ public void update_exclusivelyManagedDeviceWithoutPackageInstalled_addDevice()
+ throws Exception {
+ final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ final String exclusiveManagerName =
+ BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+ FAKE_EXCLUSIVE_MANAGER_NAME);
+ cachedDevices.add(mCachedBluetoothDevice);
+
+ when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+ exclusiveManagerName.getBytes());
+
+ doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getPackageInfo(
+ exclusiveManagerName, 0);
+
+ mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ }
}