Merge "List most recently disconnected devices in the List"
This commit is contained in:
committed by
Android (Google) Code Review
commit
08b44c42d9
@@ -74,13 +74,6 @@ public class InfoMediaManager extends MediaManager {
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getControlCategoryByPackageName(String packageName) {
|
||||
//TODO(b/117129183): Use package name to get ControlCategory.
|
||||
//Since api not ready, return fixed ControlCategory for prototype.
|
||||
return "com.google.android.gms.cast.CATEGORY_CAST";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScan() {
|
||||
mRouterManager.unregisterCallback(mMediaRouterCallback);
|
||||
@@ -192,5 +185,10 @@ public class InfoMediaManager extends MediaManager {
|
||||
public void onRoutesChanged(List<MediaRoute2Info> routes) {
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRoutesRemoved(List<MediaRoute2Info> routes) {
|
||||
refreshDevices();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
@@ -26,13 +28,13 @@ import androidx.annotation.IntDef;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -66,9 +68,16 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
@VisibleForTesting
|
||||
List<MediaDevice> mMediaDevices = new ArrayList<>();
|
||||
@VisibleForTesting
|
||||
List<MediaDevice> mDisconnectedMediaDevices = new ArrayList<>();
|
||||
@VisibleForTesting
|
||||
MediaDevice mPhoneDevice;
|
||||
@VisibleForTesting
|
||||
MediaDevice mCurrentConnectedDevice;
|
||||
@VisibleForTesting
|
||||
DeviceAttributeChangeCallback mDeviceAttributeChangeCallback =
|
||||
new DeviceAttributeChangeCallback();
|
||||
@VisibleForTesting
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
/**
|
||||
* Register to start receiving callbacks for MediaDevice events.
|
||||
@@ -89,6 +98,7 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
mPackageName = packageName;
|
||||
mLocalBluetoothManager =
|
||||
LocalBluetoothManager.getInstance(context, /* onInitCallback= */ null);
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (mLocalBluetoothManager == null) {
|
||||
Log.e(TAG, "Bluetooth is not supported on this device");
|
||||
return;
|
||||
@@ -164,7 +174,7 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
}
|
||||
|
||||
void dispatchDeviceListUpdate() {
|
||||
Collections.sort(mMediaDevices, COMPARATOR);
|
||||
//TODO(b/149260820): Use new rule to rank device once device type api is ready.
|
||||
for (DeviceCallback callback : getCallbacks()) {
|
||||
callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices));
|
||||
}
|
||||
@@ -278,12 +288,44 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
public void onDeviceListAdded(List<MediaDevice> devices) {
|
||||
mMediaDevices.clear();
|
||||
mMediaDevices.addAll(devices);
|
||||
mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
|
||||
|
||||
final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice();
|
||||
mCurrentConnectedDevice = infoMediaDevice != null
|
||||
? infoMediaDevice : updateCurrentConnectedDevice();
|
||||
dispatchDeviceListUpdate();
|
||||
}
|
||||
|
||||
private List<MediaDevice> buildDisconnectedBluetoothDevice() {
|
||||
for (MediaDevice device : mDisconnectedMediaDevices) {
|
||||
((BluetoothMediaDevice) device).getCachedDevice()
|
||||
.unregisterCallback(mDeviceAttributeChangeCallback);
|
||||
}
|
||||
mDisconnectedMediaDevices.clear();
|
||||
final List<BluetoothDevice> bluetoothDevices =
|
||||
mBluetoothAdapter.getMostRecentlyConnectedDevices();
|
||||
final CachedBluetoothDeviceManager cachedDeviceManager =
|
||||
mLocalBluetoothManager.getCachedDeviceManager();
|
||||
|
||||
for (BluetoothDevice device : bluetoothDevices) {
|
||||
final CachedBluetoothDevice cachedDevice =
|
||||
cachedDeviceManager.findDevice(device);
|
||||
if (cachedDevice != null) {
|
||||
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
|
||||
&& !cachedDevice.isConnected()) {
|
||||
final MediaDevice mediaDevice = new BluetoothMediaDevice(mContext,
|
||||
cachedDevice,
|
||||
null, null, mPackageName);
|
||||
if (!mMediaDevices.contains(mediaDevice)) {
|
||||
cachedDevice.registerCallback(mDeviceAttributeChangeCallback);
|
||||
mDisconnectedMediaDevices.add(mediaDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(mDisconnectedMediaDevices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(MediaDevice device) {
|
||||
if (mMediaDevices.contains(device)) {
|
||||
@@ -345,4 +387,17 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
*/
|
||||
default void onDeviceAttributesChanged() {};
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback is for update {@link BluetoothMediaDevice} summary when
|
||||
* {@link CachedBluetoothDevice} connection state is changed.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback {
|
||||
|
||||
@Override
|
||||
public void onDeviceAttributesChanged() {
|
||||
dispatchDeviceAttributesChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,4 +203,46 @@ public class InfoMediaManagerTest {
|
||||
|
||||
assertThat(mInfoMediaManager.connectDeviceWithoutPackageName(device)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRoutesRemoved_getAvailableRoutes_shouldAddMediaDevice() {
|
||||
final MediaRoute2Info info = mock(MediaRoute2Info.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
||||
|
||||
final List<MediaRoute2Info> routes = new ArrayList<>();
|
||||
routes.add(info);
|
||||
when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
assertThat(mediaDevice).isNull();
|
||||
|
||||
mInfoMediaManager.mMediaRouterCallback.onRoutesRemoved(routes);
|
||||
|
||||
final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
|
||||
assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
|
||||
assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
|
||||
assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRoutesRemoved_buildAllRoutes_shouldAddMediaDevice() {
|
||||
final MediaRoute2Info info = mock(MediaRoute2Info.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
||||
|
||||
final List<MediaRoute2Info> routes = new ArrayList<>();
|
||||
routes.add(info);
|
||||
when(mRouterManager.getAllRoutes()).thenReturn(routes);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
assertThat(mediaDevice).isNull();
|
||||
|
||||
mInfoMediaManager.mPackageName = "";
|
||||
mInfoMediaManager.mMediaRouterCallback.onRoutesChanged(routes);
|
||||
|
||||
final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
|
||||
assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
|
||||
assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,17 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -40,11 +44,14 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothAdapter.class})
|
||||
public class LocalMediaManagerTest {
|
||||
|
||||
private static final String TEST_DEVICE_ID_1 = "device_id_1";
|
||||
@@ -69,11 +76,15 @@ public class LocalMediaManagerTest {
|
||||
|
||||
private Context mContext;
|
||||
private LocalMediaManager mLocalMediaManager;
|
||||
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
|
||||
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
|
||||
mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(bluetoothDevices);
|
||||
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
|
||||
when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
@@ -81,6 +92,7 @@ public class LocalMediaManagerTest {
|
||||
|
||||
mLocalMediaManager = new LocalMediaManager(mContext, mLocalBluetoothManager,
|
||||
mInfoMediaManager, "com.test.packagename");
|
||||
mLocalMediaManager.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -419,4 +431,50 @@ public class LocalMediaManagerTest {
|
||||
MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
|
||||
assertThat(activeDevices).containsExactly(device3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAttributesChanged_shouldBeCalled() {
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
|
||||
mLocalMediaManager.mDeviceAttributeChangeCallback.onDeviceAttributesChanged();
|
||||
|
||||
verify(mCallback).onDeviceAttributesChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceListAdded_haveDisconnectedDevice_addDisconnectedDevice() {
|
||||
final List<MediaDevice> devices = new ArrayList<>();
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
final MediaDevice device3 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
devices.add(device1);
|
||||
devices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(device3);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
|
||||
final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
final CachedBluetoothDeviceManager cachedManager = mock(CachedBluetoothDeviceManager.class);
|
||||
bluetoothDevices.add(bluetoothDevice);
|
||||
mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(bluetoothDevices);
|
||||
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(cachedManager);
|
||||
when(cachedManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
|
||||
when(cachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||
when(cachedDevice.isConnected()).thenReturn(false);
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
|
||||
when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settingslib.testutils.shadow;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
|
||||
@@ -29,6 +30,7 @@ import java.util.List;
|
||||
public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
|
||||
|
||||
private List<Integer> mSupportedProfiles;
|
||||
private List<BluetoothDevice> mMostRecentlyConnectedDevices;
|
||||
private BluetoothProfile.ServiceListener mServiceListener;
|
||||
|
||||
@Implementation
|
||||
@@ -50,4 +52,13 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto
|
||||
public void setSupportedProfiles(List<Integer> supportedProfiles) {
|
||||
mSupportedProfiles = supportedProfiles;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<BluetoothDevice> getMostRecentlyConnectedDevices() {
|
||||
return mMostRecentlyConnectedDevices;
|
||||
}
|
||||
|
||||
public void setMostRecentlyConnectedDevices(List<BluetoothDevice> list) {
|
||||
mMostRecentlyConnectedDevices = list;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user