Merge changes from topic "media_output_slice"
* changes: Add test case for media manager Add constants for launch MediaOutput slice Add onConnectedDeviceChanged() onServiceConnected() callback
This commit is contained in:
committed by
Android (Google) Code Review
commit
39adac52d0
@@ -74,6 +74,7 @@ public class A2dpProfile implements LocalBluetoothProfile {
|
||||
device.refresh();
|
||||
}
|
||||
mIsProfileReady=true;
|
||||
mProfileManager.callServiceConnectedListeners();
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(int profile) {
|
||||
|
||||
@@ -71,8 +71,8 @@ public class HearingAidProfile implements LocalBluetoothProfile {
|
||||
|
||||
// Check current list of CachedDevices to see if any are Hearing Aid devices.
|
||||
mDeviceManager.updateHearingAidsDevices();
|
||||
|
||||
mIsProfileReady=true;
|
||||
mProfileManager.callServiceConnectedListeners();
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(int profile) {
|
||||
|
||||
@@ -54,17 +54,17 @@ public class BluetoothMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() {
|
||||
public boolean connect() {
|
||||
//TODO(b/117129183): add callback to notify LocalMediaManager connection state.
|
||||
mIsConnected = mCachedDevice.setActive();
|
||||
super.connect();
|
||||
Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
|
||||
final boolean isConnected = mCachedDevice.setActive();
|
||||
setConnectedRecord();
|
||||
Log.d(TAG, "connect() device : " + getName() + ", is selected : " + isConnected);
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
//TODO(b/117129183): disconnected last select device
|
||||
mIsConnected = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,7 @@ 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.util.Log;
|
||||
|
||||
@@ -35,36 +36,48 @@ import java.util.List;
|
||||
/**
|
||||
* BluetoothMediaManager provide interface to get Bluetooth device list.
|
||||
*/
|
||||
public class BluetoothMediaManager extends MediaManager implements BluetoothCallback {
|
||||
public class BluetoothMediaManager extends MediaManager implements BluetoothCallback,
|
||||
LocalBluetoothProfileManager.ServiceListener {
|
||||
|
||||
private static final String TAG = "BluetoothMediaManager";
|
||||
|
||||
private final DeviceAttributeChangeCallback mCachedDeviceCallback =
|
||||
new DeviceAttributeChangeCallback();
|
||||
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
private LocalBluetoothProfileManager mProfileManager;
|
||||
private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
|
||||
|
||||
private MediaDevice mLastAddedDevice;
|
||||
private MediaDevice mLastRemovedDevice;
|
||||
|
||||
private boolean mIsA2dpProfileReady = false;
|
||||
private boolean mIsHearingAidProfileReady = false;
|
||||
|
||||
BluetoothMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
|
||||
Notification notification) {
|
||||
super(context, notification);
|
||||
|
||||
mLocalBluetoothManager = localBluetoothManager;
|
||||
mProfileManager = mLocalBluetoothManager.getProfileManager();
|
||||
mCachedBluetoothDeviceManager = mLocalBluetoothManager.getCachedDeviceManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
mMediaDevices.clear();
|
||||
mLocalBluetoothManager.getEventManager().registerCallback(this);
|
||||
buildBluetoothDeviceList();
|
||||
dispatchDeviceListAdded();
|
||||
|
||||
// The profile may not ready when calling startScan().
|
||||
// Device status are all disconnected since profiles are not ready to connected.
|
||||
// In this case, we observe onServiceConnected() in LocalBluetoothProfileManager.
|
||||
// When A2dpProfile or HearingAidProfile is connected will call buildBluetoothDeviceList()
|
||||
// again to find the connected devices.
|
||||
if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
|
||||
mProfileManager.addServiceListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildBluetoothDeviceList() {
|
||||
mMediaDevices.clear();
|
||||
addConnectedA2dpDevices();
|
||||
addConnectedHearingAidDevices();
|
||||
}
|
||||
@@ -77,12 +90,10 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
}
|
||||
|
||||
final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
|
||||
final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
|
||||
mLocalBluetoothManager.getCachedDeviceManager();
|
||||
|
||||
for (BluetoothDevice device : devices) {
|
||||
final CachedBluetoothDevice cachedDevice =
|
||||
cachedBluetoothDeviceManager.findDevice(device);
|
||||
mCachedBluetoothDeviceManager.findDevice(device);
|
||||
|
||||
if (cachedDevice == null) {
|
||||
Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
|
||||
@@ -96,6 +107,8 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
addMediaDevice(cachedDevice);
|
||||
}
|
||||
}
|
||||
|
||||
mIsA2dpProfileReady = a2dpProfile.isProfileReady();
|
||||
}
|
||||
|
||||
private void addConnectedHearingAidDevices() {
|
||||
@@ -107,12 +120,10 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
|
||||
final List<Long> devicesHiSyncIds = new ArrayList<>();
|
||||
final List<BluetoothDevice> devices = hapProfile.getConnectedDevices();
|
||||
final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
|
||||
mLocalBluetoothManager.getCachedDeviceManager();
|
||||
|
||||
for (BluetoothDevice device : devices) {
|
||||
final CachedBluetoothDevice cachedDevice =
|
||||
cachedBluetoothDeviceManager.findDevice(device);
|
||||
mCachedBluetoothDeviceManager.findDevice(device);
|
||||
|
||||
if (cachedDevice == null) {
|
||||
Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
|
||||
@@ -130,13 +141,14 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
addMediaDevice(cachedDevice);
|
||||
}
|
||||
}
|
||||
|
||||
mIsHearingAidProfileReady = hapProfile.isProfileReady();
|
||||
}
|
||||
|
||||
private void addMediaDevice(CachedBluetoothDevice cachedDevice) {
|
||||
MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
|
||||
if (mediaDevice == null) {
|
||||
mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice);
|
||||
cachedDevice.registerCallback(mCachedDeviceCallback);
|
||||
mLastAddedDevice = mediaDevice;
|
||||
mMediaDevices.add(mediaDevice);
|
||||
}
|
||||
@@ -145,16 +157,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
@Override
|
||||
public void stopScan() {
|
||||
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
|
||||
unregisterCachedDeviceCallback();
|
||||
}
|
||||
|
||||
private void unregisterCachedDeviceCallback() {
|
||||
for (MediaDevice device : mMediaDevices) {
|
||||
if (device instanceof BluetoothMediaDevice) {
|
||||
((BluetoothMediaDevice) device).getCachedDevice()
|
||||
.unregisterCallback(mCachedDeviceCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,8 +168,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
final List<MediaDevice> removeDevicesList = new ArrayList<>();
|
||||
for (MediaDevice device : mMediaDevices) {
|
||||
if (device instanceof BluetoothMediaDevice) {
|
||||
((BluetoothMediaDevice) device).getCachedDevice()
|
||||
.unregisterCallback(mCachedDeviceCallback);
|
||||
removeDevicesList.add(device);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
private void removeMediaDevice(CachedBluetoothDevice cachedDevice) {
|
||||
final MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
|
||||
if (mediaDevice != null) {
|
||||
cachedDevice.unregisterCallback(mCachedDeviceCallback);
|
||||
mLastRemovedDevice = mediaDevice;
|
||||
mMediaDevices.remove(mediaDevice);
|
||||
}
|
||||
@@ -252,10 +251,34 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
|
||||
dispatchDeviceRemoved(cachedDevice);
|
||||
}
|
||||
}
|
||||
class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback {
|
||||
@Override
|
||||
public void onDeviceAttributesChanged() {
|
||||
dispatchDeviceAttributesChanged();
|
||||
|
||||
@Override
|
||||
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
|
||||
Log.d(TAG, "onActiveDeviceChanged : device : "
|
||||
+ activeDevice + ", profile : " + bluetoothProfile);
|
||||
if (BluetoothProfile.HEARING_AID == bluetoothProfile
|
||||
|| BluetoothProfile.A2DP == bluetoothProfile) {
|
||||
final String id = activeDevice == null
|
||||
? PhoneMediaDevice.ID : MediaDeviceUtils.getId(activeDevice);
|
||||
dispatchConnectedDeviceChanged(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
|
||||
buildBluetoothDeviceList();
|
||||
dispatchDeviceListAdded();
|
||||
}
|
||||
|
||||
//Remove the listener once a2dpProfile and hearingAidProfile are ready.
|
||||
if (mIsA2dpProfileReady && mIsHearingAidProfileReady) {
|
||||
mProfileManager.removeServiceListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class InfoMediaDevice extends MediaDevice {
|
||||
|
||||
@Override
|
||||
public int getIcon() {
|
||||
//TODO(b/117129183): This is not final icon for cast device, just for demo.
|
||||
//TODO(b/121083246): This is not final icon for cast device, just for demo.
|
||||
return R.drawable.ic_settings_print;
|
||||
}
|
||||
|
||||
@@ -53,15 +54,15 @@ public class InfoMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() {
|
||||
//TODO(b/117129183): use MediaController2 to transfer media
|
||||
mIsConnected = true;
|
||||
super.connect();
|
||||
public boolean connect() {
|
||||
//TODO(b/121083246): use SystemApi to transfer media
|
||||
setConnectedRecord();
|
||||
Toast.makeText(mContext, "This is cast device !", Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
//TODO(b/117129183): disconnected last select device
|
||||
mIsConnected = false;
|
||||
//TODO(b/121083246): disconnected last select device
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.util.Log;
|
||||
import androidx.mediarouter.media.MediaRouteSelector;
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* InfoMediaManager provide interface to get InfoMediaDevice list.
|
||||
*/
|
||||
@@ -29,9 +31,13 @@ public class InfoMediaManager extends MediaManager {
|
||||
|
||||
private static final String TAG = "InfoMediaManager";
|
||||
|
||||
private final MediaRouterCallback mMediaRouterCallback = new MediaRouterCallback();
|
||||
@VisibleForTesting
|
||||
final MediaRouterCallback mMediaRouterCallback = new MediaRouterCallback();
|
||||
@VisibleForTesting
|
||||
MediaRouteSelector mSelector;
|
||||
@VisibleForTesting
|
||||
MediaRouter mMediaRouter;
|
||||
|
||||
private MediaRouter mMediaRouter;
|
||||
private String mPackageName;
|
||||
|
||||
InfoMediaManager(Context context, String packageName, Notification notification) {
|
||||
@@ -39,24 +45,20 @@ public class InfoMediaManager extends MediaManager {
|
||||
|
||||
mMediaRouter = MediaRouter.getInstance(context);
|
||||
mPackageName = packageName;
|
||||
mSelector = new MediaRouteSelector.Builder()
|
||||
.addControlCategory(getControlCategoryByPackageName(mPackageName))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
mMediaDevices.clear();
|
||||
startScanCastDevice();
|
||||
}
|
||||
|
||||
private void startScanCastDevice() {
|
||||
final MediaRouteSelector selector = new MediaRouteSelector.Builder()
|
||||
.addControlCategory(getControlCategoryByPackageName(mPackageName))
|
||||
.build();
|
||||
|
||||
mMediaRouter.addCallback(selector, mMediaRouterCallback,
|
||||
mMediaRouter.addCallback(mSelector, mMediaRouterCallback,
|
||||
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
|
||||
}
|
||||
|
||||
private String getControlCategoryByPackageName(String packageName) {
|
||||
@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/4F8B3483";
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
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.LocalBluetoothManager;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -50,16 +53,20 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
}
|
||||
|
||||
private final Collection<DeviceCallback> mCallbacks = new ArrayList<>();
|
||||
private final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
|
||||
@VisibleForTesting
|
||||
final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
|
||||
|
||||
private Context mContext;
|
||||
private List<MediaDevice> mMediaDevices = new ArrayList<>();
|
||||
private BluetoothMediaManager mBluetoothMediaManager;
|
||||
private InfoMediaManager mInfoMediaManager;
|
||||
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
private MediaDevice mLastConnectedDevice;
|
||||
private MediaDevice mPhoneDevice;
|
||||
|
||||
@VisibleForTesting
|
||||
List<MediaDevice> mMediaDevices = new ArrayList<>();
|
||||
@VisibleForTesting
|
||||
MediaDevice mPhoneDevice;
|
||||
@VisibleForTesting
|
||||
MediaDevice mCurrentConnectedDevice;
|
||||
|
||||
/**
|
||||
* Register to start receiving callbacks for MediaDevice events.
|
||||
@@ -93,28 +100,40 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
mInfoMediaManager = new InfoMediaManager(context, packageName, notification);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
LocalMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
|
||||
BluetoothMediaManager bluetoothMediaManager, InfoMediaManager infoMediaManager) {
|
||||
mContext = context;
|
||||
mLocalBluetoothManager = localBluetoothManager;
|
||||
mBluetoothMediaManager = bluetoothMediaManager;
|
||||
mInfoMediaManager = infoMediaManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the MediaDevice to transfer media
|
||||
* @param connectDevice the MediaDevice
|
||||
*/
|
||||
public void connectDevice(MediaDevice connectDevice) {
|
||||
if (connectDevice == mLastConnectedDevice) {
|
||||
final MediaDevice device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
|
||||
if (device == mCurrentConnectedDevice) {
|
||||
Log.d(TAG, "connectDevice() this device all ready connected! : " + device.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mLastConnectedDevice != null) {
|
||||
mLastConnectedDevice.disconnect();
|
||||
//TODO(b/121083246): Update it once remote media API is ready.
|
||||
if (mCurrentConnectedDevice != null && !(connectDevice instanceof InfoMediaDevice)) {
|
||||
mCurrentConnectedDevice.disconnect();
|
||||
}
|
||||
|
||||
connectDevice.connect();
|
||||
if (connectDevice.isConnected()) {
|
||||
mLastConnectedDevice = connectDevice;
|
||||
final boolean isConnected = device.connect();
|
||||
if (isConnected) {
|
||||
mCurrentConnectedDevice = device;
|
||||
}
|
||||
|
||||
final int state = connectDevice.isConnected()
|
||||
final int state = isConnected
|
||||
? MediaDeviceState.STATE_CONNECTED
|
||||
: MediaDeviceState.STATE_DISCONNECTED;
|
||||
dispatchSelectedDeviceStateChanged(connectDevice, state);
|
||||
dispatchSelectedDeviceStateChanged(device, state);
|
||||
}
|
||||
|
||||
void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) {
|
||||
@@ -189,6 +208,31 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the current connected MediaDevice.
|
||||
*
|
||||
* @return MediaDevice
|
||||
*/
|
||||
public MediaDevice getCurrentConnectedDevice() {
|
||||
return mCurrentConnectedDevice;
|
||||
}
|
||||
|
||||
private MediaDevice updateCurrentConnectedDevice() {
|
||||
for (MediaDevice device : mMediaDevices) {
|
||||
if (device instanceof BluetoothMediaDevice) {
|
||||
if (isConnected(((BluetoothMediaDevice) device).getCachedDevice())) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mMediaDevices.contains(mPhoneDevice) ? mPhoneDevice : null;
|
||||
}
|
||||
|
||||
private boolean isConnected(CachedBluetoothDevice device) {
|
||||
return device.isActiveDevice(BluetoothProfile.A2DP)
|
||||
|| device.isActiveDevice(BluetoothProfile.HEARING_AID);
|
||||
}
|
||||
|
||||
class MediaDeviceCallback implements MediaManager.MediaDeviceCallback {
|
||||
@Override
|
||||
public void onDeviceAdded(MediaDevice device) {
|
||||
@@ -201,8 +245,13 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
|
||||
@Override
|
||||
public void onDeviceListAdded(List<MediaDevice> devices) {
|
||||
mMediaDevices.addAll(devices);
|
||||
for (MediaDevice device : devices) {
|
||||
if (getMediaDeviceById(mMediaDevices, device.getId()) == null) {
|
||||
mMediaDevices.add(device);
|
||||
}
|
||||
}
|
||||
addPhoneDeviceIfNecessary();
|
||||
mCurrentConnectedDevice = updateCurrentConnectedDevice();
|
||||
dispatchDeviceListUpdate();
|
||||
}
|
||||
|
||||
@@ -226,6 +275,20 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
public void onDeviceAttributesChanged() {
|
||||
dispatchDeviceListUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedDeviceChanged(String id) {
|
||||
final MediaDevice connectDevice = getMediaDeviceById(mMediaDevices, id);
|
||||
|
||||
if (connectDevice == mCurrentConnectedDevice) {
|
||||
Log.d(TAG, "onConnectedDeviceChanged() this device all ready connected! : "
|
||||
+ connectDevice.getName());
|
||||
return;
|
||||
}
|
||||
mCurrentConnectedDevice = connectDevice;
|
||||
|
||||
dispatchDeviceListUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
||||
|
||||
private int mConnectedRecord;
|
||||
|
||||
protected boolean mIsConnected = false;
|
||||
protected Context mContext;
|
||||
protected int mType;
|
||||
|
||||
@@ -56,15 +55,6 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
||||
getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the MediaDevice is be connected to transfer.
|
||||
*
|
||||
* @return true if the MediaDevice is be connected to transfer, false otherwise.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return mIsConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name from MediaDevice.
|
||||
*
|
||||
@@ -87,8 +77,12 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
||||
|
||||
/**
|
||||
* Transfer MediaDevice for media
|
||||
*
|
||||
* @return result of transfer media
|
||||
*/
|
||||
public void connect() {
|
||||
public abstract boolean connect();
|
||||
|
||||
void setConnectedRecord() {
|
||||
mConnectedRecord++;
|
||||
ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(),
|
||||
mConnectedRecord);
|
||||
|
||||
@@ -96,7 +96,7 @@ public abstract class MediaManager {
|
||||
protected void dispatchDeviceListAdded() {
|
||||
synchronized (mCallbacks) {
|
||||
for (MediaDeviceCallback callback : mCallbacks) {
|
||||
callback.onDeviceListAdded(mMediaDevices);
|
||||
callback.onDeviceListAdded(new ArrayList<>(mMediaDevices));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,10 +109,10 @@ public abstract class MediaManager {
|
||||
}
|
||||
}
|
||||
|
||||
protected void dispatchDeviceAttributesChanged() {
|
||||
protected void dispatchConnectedDeviceChanged(String id) {
|
||||
synchronized (mCallbacks) {
|
||||
for (MediaDeviceCallback callback : mCallbacks) {
|
||||
callback.onDeviceAttributesChanged();
|
||||
callback.onConnectedDeviceChanged(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,5 +153,12 @@ public abstract class MediaManager {
|
||||
* Callback for notifying MediaDevice attributes is changed.
|
||||
*/
|
||||
void onDeviceAttributesChanged();
|
||||
|
||||
/**
|
||||
* Callback for notifying connected MediaDevice is changed.
|
||||
*
|
||||
* @param id the id of MediaDevice
|
||||
*/
|
||||
void onConnectedDeviceChanged(String id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
/**
|
||||
* Class to access MediaOutput constants.
|
||||
*/
|
||||
public class MediaOutputSliceConstants {
|
||||
|
||||
/**
|
||||
* Key for the Media output setting.
|
||||
*/
|
||||
public static final String KEY_MEDIA_OUTPUT = "media_output";
|
||||
|
||||
/**
|
||||
* Activity Action: Show a settings dialog containing {@link MediaDevice} to transfer media.
|
||||
*/
|
||||
public static final String ACTION_MEDIA_OUTPUT =
|
||||
"com.android.settings.panel.action.MEDIA_OUTPUT";
|
||||
|
||||
/**
|
||||
* An string extra specifying a media package name.
|
||||
*/
|
||||
public static final String EXTRA_PACKAGE_NAME =
|
||||
"com.android.settings.panel.extra.PACKAGE_NAME";
|
||||
}
|
||||
@@ -62,20 +62,22 @@ public class PhoneMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() {
|
||||
public boolean connect() {
|
||||
final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
|
||||
final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
|
||||
|
||||
boolean isConnected = false;
|
||||
|
||||
if (hapProfile != null && a2dpProfile != null) {
|
||||
mIsConnected = hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
|
||||
super.connect();
|
||||
isConnected = hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
|
||||
setConnectedRecord();
|
||||
}
|
||||
Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
|
||||
Log.d(TAG, "connect() device : " + getName() + ", is selected : " + isConnected);
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
//TODO(b/117129183): disconnected last select device
|
||||
mIsConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BluetoothMediaDeviceTest {
|
||||
|
||||
@Mock
|
||||
private CachedBluetoothDevice mDevice;
|
||||
|
||||
private Context mContext;
|
||||
private BluetoothMediaDevice mBluetoothMediaDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
when(mDevice.isActiveDevice(BluetoothProfile.A2DP)).thenReturn(true);
|
||||
when(mDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true);
|
||||
|
||||
mBluetoothMediaDevice = new BluetoothMediaDevice(mContext, mDevice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_setActiveSuccess_isConnectedReturnTrue() {
|
||||
when(mDevice.setActive()).thenReturn(true);
|
||||
|
||||
assertThat(mBluetoothMediaDevice.connect()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_setActiveFail_isConnectedReturnFalse() {
|
||||
when(mDevice.setActive()).thenReturn(false);
|
||||
|
||||
assertThat(mBluetoothMediaDevice.connect()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
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.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||
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 org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BluetoothMediaManagerTest {
|
||||
|
||||
private static final String TEST_ADDRESS = "11:22:33:44:55:66";
|
||||
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mProfileManager;
|
||||
@Mock
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private HearingAidProfile mHapProfile;
|
||||
@Mock
|
||||
private CachedBluetoothDeviceManager mCachedDeviceManager;
|
||||
@Mock
|
||||
private BluetoothEventManager mEventManager;
|
||||
@Mock
|
||||
private MediaManager.MediaDeviceCallback mCallback;
|
||||
|
||||
private BluetoothMediaManager mMediaManager;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
|
||||
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
when(mProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
|
||||
when(mLocalBluetoothManager.getEventManager()).thenReturn(mEventManager);
|
||||
|
||||
mMediaManager = new BluetoothMediaManager(mContext, mLocalBluetoothManager, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_haveA2dpProfileConnectedBluetoothDevice_shouldAddDevice() {
|
||||
final List<BluetoothDevice> devices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
|
||||
devices.add(bluetoothDevice);
|
||||
|
||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
|
||||
when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
|
||||
when(cachedDevice.isConnected()).thenReturn(true);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.startScan();
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(devices.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_haveA2dpProfileDisconnectedBluetoothDevice_shouldNotAddDevice() {
|
||||
final List<BluetoothDevice> devices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
|
||||
devices.add(bluetoothDevice);
|
||||
|
||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
|
||||
when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
|
||||
when(cachedDevice.isConnected()).thenReturn(false);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.startScan();
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_noA2dpProfileBluetoothDevice_shouldNotAddDevice() {
|
||||
final List<BluetoothDevice> devices = new ArrayList<>();
|
||||
|
||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(devices);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.startScan();
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_haveHapProfileConnectedBluetoothDevice_shouldAddDevice() {
|
||||
final List<BluetoothDevice> devices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
|
||||
devices.add(bluetoothDevice);
|
||||
|
||||
when(mHapProfile.getConnectedDevices()).thenReturn(devices);
|
||||
when(mCachedDeviceManager.findDevice(bluetoothDevice)).thenReturn(cachedDevice);
|
||||
when(cachedDevice.isConnected()).thenReturn(true);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.startScan();
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(devices.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_noHapProfileBluetoothDevice_shouldNotAddDevice() {
|
||||
final List<BluetoothDevice> devices = new ArrayList<>();
|
||||
|
||||
when(mHapProfile.getConnectedDevices()).thenReturn(devices);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.startScan();
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starScan_a2dpAndHapProfileNotReady_shouldRegisterCallback() {
|
||||
final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
mDevices.add(cachedDevice);
|
||||
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
|
||||
when(mA2dpProfile.isProfileReady()).thenReturn(false);
|
||||
when(mHapProfile.isProfileReady()).thenReturn(false);
|
||||
|
||||
mMediaManager.startScan();
|
||||
|
||||
verify(mProfileManager).addServiceListener(mMediaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starScan_a2dpAndHapProfileReady_shouldNotRegisterCallback() {
|
||||
final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
mDevices.add(cachedDevice);
|
||||
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
|
||||
when(mA2dpProfile.isProfileReady()).thenReturn(true);
|
||||
when(mHapProfile.isProfileReady()).thenReturn(true);
|
||||
|
||||
mMediaManager.startScan();
|
||||
|
||||
verify(mProfileManager, never()).addServiceListener(mMediaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onServiceConnected_a2dpAndHapProfileNotReady_doNothing() {
|
||||
final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
mDevices.add(cachedDevice);
|
||||
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
|
||||
when(mA2dpProfile.isProfileReady()).thenReturn(false);
|
||||
when(mHapProfile.isProfileReady()).thenReturn(false);
|
||||
|
||||
mMediaManager.startScan();
|
||||
mMediaManager.onServiceConnected();
|
||||
|
||||
verify(mProfileManager, never()).removeServiceListener(mMediaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAttributesChanged_a2dpAndHapProfileReady_shouldUnregisterCallback() {
|
||||
final Collection<CachedBluetoothDevice> mDevices = new ArrayList<>();
|
||||
final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
|
||||
mDevices.add(cachedDevice);
|
||||
|
||||
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
|
||||
when(mA2dpProfile.isProfileReady()).thenReturn(true);
|
||||
when(mHapProfile.isProfileReady()).thenReturn(true);
|
||||
|
||||
mMediaManager.startScan();
|
||||
mMediaManager.onServiceConnected();
|
||||
|
||||
verify(mProfileManager).removeServiceListener(mMediaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBluetoothStateChanged_bluetoothStateIsOn_callOnDeviceListAdded() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
|
||||
|
||||
verify(mCallback).onDeviceListAdded(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBluetoothStateChanged_bluetoothStateIsOff_callOnDeviceListRemoved() {
|
||||
final BluetoothMediaDevice device1 = mock(BluetoothMediaDevice.class);
|
||||
final BluetoothMediaDevice device2 = mock(BluetoothMediaDevice.class);
|
||||
mMediaManager.mMediaDevices.add(device1);
|
||||
mMediaManager.mMediaDevices.add(device2);
|
||||
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceListRemoved(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_cachedDeviceIsConnected_callOnDeviceAdded() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(true);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(true);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onDeviceAdded(device);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
verify(mCallback).onDeviceAdded(any());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_cachedDeviceIsDisconnected_doNothing() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(false);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(false);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onDeviceAdded(device);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback, never()).onDeviceAdded(any());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceDeleted_cachedDeviceIsConnected_doNothing() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
|
||||
mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(true);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(true);
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onDeviceDeleted(device);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
verify(mCallback, never()).onDeviceRemoved(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceDeleted_cachedDeviceIsDisconnected_callOnDeviceRemoved() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
|
||||
mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(false);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(false);
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onDeviceDeleted(device);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceRemoved(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProfileConnectionStateChanged_cachedDeviceIsConnect_callOnDeviceAdded() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(true);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(true);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onProfileConnectionStateChanged(device, 0, 0);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
verify(mCallback).onDeviceAdded(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onProfileConnectionStateChanged_cachedDeviceIsDisconnect_callOnDeviceRemoved() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
|
||||
mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(false);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(false);
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onProfileConnectionStateChanged(device, 0, 0);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceRemoved(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAclConnectionStateChanged_cachedDeviceIsConnect_callOnDeviceAdded() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(true);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(true);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onAclConnectionStateChanged(device, 0);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
verify(mCallback).onDeviceAdded(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAclConnectionStateChanged_cachedDeviceIsDisconnect_callOnDeviceRemoved() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
|
||||
mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
|
||||
|
||||
when(device.isConnectedHearingAidDevice()).thenReturn(false);
|
||||
when(device.isConnectedA2dpDevice()).thenReturn(false);
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).hasSize(1);
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onAclConnectionStateChanged(device, 0);
|
||||
|
||||
assertThat(mMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceRemoved(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActiveDeviceChanged_isHapProfile_callOnActiveDeviceChanged() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.HEARING_AID);
|
||||
|
||||
verify(mCallback).onConnectedDeviceChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActiveDeviceChanged_isA2dpProfile_callOnActiveDeviceChanged() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.A2DP);
|
||||
|
||||
verify(mCallback).onConnectedDeviceChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActiveDeviceChanged_isNotA2dpAndHapProfile_doNothing() {
|
||||
final CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
|
||||
|
||||
when(device.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
mMediaManager.onActiveDeviceChanged(device, BluetoothProfile.HEALTH);
|
||||
|
||||
verify(mCallback, never()).onConnectedDeviceChanged(any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouteSelector;
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class InfoMediaManagerTest {
|
||||
|
||||
private static final String TEST_PACKAGE_NAME = "com.test.packagename";
|
||||
private static final String TEST_ID = "test_id";
|
||||
|
||||
@Mock
|
||||
private MediaRouter mMediaRouter;
|
||||
@Mock
|
||||
private MediaRouteSelector mSelector;
|
||||
|
||||
private InfoMediaManager mInfoMediaManager;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
mInfoMediaManager = new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null);
|
||||
mInfoMediaManager.mMediaRouter = mMediaRouter;
|
||||
mInfoMediaManager.mSelector = mSelector;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopScan_shouldRemoveCallback() {
|
||||
mInfoMediaManager.stopScan();
|
||||
|
||||
verify(mMediaRouter).removeCallback(mInfoMediaManager.mMediaRouterCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_shouldAddCallback() {
|
||||
mInfoMediaManager.startScan();
|
||||
|
||||
verify(mMediaRouter).addCallback(mSelector, mInfoMediaManager.mMediaRouterCallback,
|
||||
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRouteAdded_mediaDeviceNotExistInList_addMediaDevice() {
|
||||
final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
assertThat(mediaDevice).isNull();
|
||||
|
||||
mInfoMediaManager.mMediaRouterCallback.onRouteAdded(mMediaRouter, info);
|
||||
|
||||
final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
|
||||
assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRouteAdded_mediaDeviceExistInList_doNothing() {
|
||||
final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
final InfoMediaDevice infoDevice = new InfoMediaDevice(mContext, info);
|
||||
mInfoMediaManager.mMediaDevices.add(infoDevice);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
final int size = mInfoMediaManager.mMediaDevices.size();
|
||||
assertThat(mediaDevice).isNotNull();
|
||||
|
||||
mInfoMediaManager.mMediaRouterCallback.onRouteAdded(mMediaRouter, info);
|
||||
|
||||
assertThat(mInfoMediaManager.mMediaDevices).hasSize(size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRouteRemoved_mediaDeviceExistInList_removeMediaDevice() {
|
||||
final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
final InfoMediaDevice infoDevice = new InfoMediaDevice(mContext, info);
|
||||
mInfoMediaManager.mMediaDevices.add(infoDevice);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
assertThat(mediaDevice).isNotNull();
|
||||
assertThat(mInfoMediaManager.mMediaDevices).hasSize(1);
|
||||
|
||||
mInfoMediaManager.mMediaRouterCallback.onRouteRemoved(mMediaRouter, info);
|
||||
|
||||
assertThat(mInfoMediaManager.mMediaDevices).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRouteRemoved_mediaDeviceNotExistInList_doNothing() {
|
||||
final MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
|
||||
when(info.getId()).thenReturn(TEST_ID);
|
||||
|
||||
final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
|
||||
final int size = mInfoMediaManager.mMediaDevices.size();
|
||||
assertThat(mediaDevice).isNull();
|
||||
|
||||
mInfoMediaManager.mMediaRouterCallback.onRouteRemoved(mMediaRouter, info);
|
||||
|
||||
assertThat(mInfoMediaManager.mMediaDevices).hasSize(size);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class LocalMediaManagerTest {
|
||||
|
||||
private static final String TEST_DEVICE_ID_1 = "device_id_1";
|
||||
private static final String TEST_DEVICE_ID_2 = "device_id_2";
|
||||
private static final String TEST_DEVICE_ID_3 = "device_id_3";
|
||||
private static final String TEST_CURRENT_DEVICE_ID = "currentDevice_id";
|
||||
|
||||
@Mock
|
||||
private BluetoothMediaManager mBluetoothMediaManager;
|
||||
@Mock
|
||||
private InfoMediaManager mInfoMediaManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private LocalMediaManager.DeviceCallback mCallback;
|
||||
@Mock
|
||||
private HearingAidProfile mHapProfile;
|
||||
@Mock
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mLocalProfileManager;
|
||||
|
||||
private Context mContext;
|
||||
private LocalMediaManager mLocalMediaManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
|
||||
when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
|
||||
|
||||
mLocalMediaManager = new LocalMediaManager(mContext, mLocalBluetoothManager,
|
||||
mBluetoothMediaManager, mInfoMediaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startScan_mediaDevicesListShouldBeClear() {
|
||||
final MediaDevice device = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(1);
|
||||
mLocalMediaManager.startScan();
|
||||
assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectDevice_deviceNotEqualCurrentConnectedDevice_connectDevice() {
|
||||
final MediaDevice currentDevice = mock(MediaDevice.class);
|
||||
final MediaDevice device = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(currentDevice);
|
||||
mLocalMediaManager.mMediaDevices.add(device);
|
||||
mLocalMediaManager.mCurrentConnectedDevice = currentDevice;
|
||||
|
||||
when(device.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(currentDevice.getId()).thenReturn(TEST_CURRENT_DEVICE_ID);
|
||||
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.connectDevice(device);
|
||||
|
||||
verify(currentDevice).disconnect();
|
||||
verify(device).connect();
|
||||
verify(mCallback).onSelectedDeviceStateChanged(any(),
|
||||
eq(LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMediaDeviceById_idExist_shouldReturnMediaDevice() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
|
||||
final MediaDevice device = mLocalMediaManager
|
||||
.getMediaDeviceById(mLocalMediaManager.mMediaDevices, TEST_DEVICE_ID_2);
|
||||
|
||||
assertThat(device.getId()).isEqualTo(TEST_DEVICE_ID_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMediaDeviceById_idNotExist_shouldReturnNull() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
|
||||
final MediaDevice device = mLocalMediaManager
|
||||
.getMediaDeviceById(mLocalMediaManager.mMediaDevices, TEST_CURRENT_DEVICE_ID);
|
||||
|
||||
assertThat(device).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_mediaDeviceAndPhoneDeviceNotExistInList_addBothDevice() {
|
||||
final MediaDevice device = mock(MediaDevice.class);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_mediaDeviceNotExistAndPhoneDeviceExistInList_addMediaDevice() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device2);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_mediaDeviceAndPhoneDeviceExistInList_doNothing() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceAdded(device1);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
verify(mCallback, never()).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceListAdded_phoneDeviceNotExistInList_addPhoneDeviceAndDevicesList() {
|
||||
final List<MediaDevice> devices = new ArrayList<>();
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
devices.add(device1);
|
||||
devices.add(device2);
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceListAdded_phoneDeviceExistInList_addDeviceList() {
|
||||
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);
|
||||
|
||||
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(4);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_phoneDeviceIsLastDeviceAfterRemoveMediaDevice_removeBothDevice() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device1);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_phoneDeviceNotLastDeviceAfterRemoveMediaDevice_removeMediaDevice() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device2);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_removeMediaDeviceNotInList_doNothing() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceRemoved(device1);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
verify(mCallback, never()).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceListRemoved_phoneDeviceIsLastDeviceAfterRemoveDeviceList_removeAll() {
|
||||
final List<MediaDevice> devices = new ArrayList<>();
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class);
|
||||
devices.add(device1);
|
||||
devices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(3);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceListRemoved(devices);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).isEmpty();
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceListRemoved_phoneDeviceNotLastDeviceAfterRemoveDeviceList_removeList() {
|
||||
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(device3);
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mMediaDevices.add(device3);
|
||||
mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(4);
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceListRemoved(devices);
|
||||
|
||||
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAttributesChanged_shouldDispatchDeviceListUpdate() {
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
|
||||
mLocalMediaManager.mMediaDeviceCallback.onDeviceAttributesChanged();
|
||||
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onConnectedDeviceChanged_connectedAndCurrentDeviceAreDifferent_notifyThemChanged() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mCurrentConnectedDevice = device1;
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onConnectedDeviceChanged(TEST_DEVICE_ID_2);
|
||||
|
||||
assertThat(mLocalMediaManager.getCurrentConnectedDevice()).isEqualTo(device2);
|
||||
verify(mCallback).onDeviceListUpdate(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onConnectedDeviceChanged_connectedAndCurrentDeviceAreSame_doNothing() {
|
||||
final MediaDevice device1 = mock(MediaDevice.class);
|
||||
final MediaDevice device2 = mock(MediaDevice.class);
|
||||
|
||||
mLocalMediaManager.mMediaDevices.add(device1);
|
||||
mLocalMediaManager.mMediaDevices.add(device2);
|
||||
mLocalMediaManager.mCurrentConnectedDevice = device1;
|
||||
|
||||
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
|
||||
|
||||
mLocalMediaManager.registerCallback(mCallback);
|
||||
mLocalMediaManager.mMediaDeviceCallback.onConnectedDeviceChanged(TEST_DEVICE_ID_1);
|
||||
|
||||
verify(mCallback, never()).onDeviceListUpdate(any());
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,11 @@ import android.content.Context;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -78,6 +81,14 @@ public class MediaDeviceTest {
|
||||
private MediaRouter.RouteInfo mRouteInfo2;
|
||||
@Mock
|
||||
private MediaRouter.RouteInfo mRouteInfo3;
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mProfileManager;
|
||||
@Mock
|
||||
private HearingAidProfile mHapProfile;
|
||||
@Mock
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private BluetoothDevice mDevice;
|
||||
|
||||
private BluetoothMediaDevice mBluetoothMediaDevice1;
|
||||
private BluetoothMediaDevice mBluetoothMediaDevice2;
|
||||
@@ -109,6 +120,10 @@ public class MediaDeviceTest {
|
||||
when(mRouteInfo1.getName()).thenReturn(DEVICE_NAME_1);
|
||||
when(mRouteInfo2.getName()).thenReturn(DEVICE_NAME_2);
|
||||
when(mRouteInfo3.getName()).thenReturn(DEVICE_NAME_3);
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
|
||||
when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
when(mProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
|
||||
when(mA2dpProfile.getActiveDevice()).thenReturn(mDevice);
|
||||
|
||||
mBluetoothMediaDevice1 = new BluetoothMediaDevice(mContext, mCachedDevice1);
|
||||
mBluetoothMediaDevice2 = new BluetoothMediaDevice(mContext, mCachedDevice2);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class MediaDeviceUtilsTest {
|
||||
|
||||
private static final String TEST_ADDRESS = "11:22:33:44:55:66";
|
||||
private static final String TEST_ROUTE_ID = "test_route_id";
|
||||
|
||||
@Mock
|
||||
private CachedBluetoothDevice mDevice;
|
||||
@Mock
|
||||
private MediaRouter.RouteInfo mRouteInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getId_returnBluetoothDeviceAddress() {
|
||||
when(mDevice.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
|
||||
final String id = MediaDeviceUtils.getId(mDevice);
|
||||
|
||||
assertThat(id).isEqualTo(TEST_ADDRESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getId_returnRouteInfoId() {
|
||||
when(mRouteInfo.getId()).thenReturn(TEST_ROUTE_ID);
|
||||
|
||||
final String id = MediaDeviceUtils.getId(mRouteInfo);
|
||||
|
||||
assertThat(id).isEqualTo(TEST_ROUTE_ID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class MediaManagerTest {
|
||||
|
||||
private static final String TEST_ID = "test_id";
|
||||
|
||||
@Mock
|
||||
private MediaManager.MediaDeviceCallback mCallback;
|
||||
@Mock
|
||||
private MediaDevice mDevice;
|
||||
|
||||
private MediaManager mMediaManager;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
when(mDevice.getId()).thenReturn(TEST_ID);
|
||||
|
||||
mMediaManager = new MediaManager(mContext, null) {
|
||||
@Override
|
||||
public void startScan() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScan() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchDeviceAdded_registerCallback_shouldDispatchCallback() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
|
||||
mMediaManager.dispatchDeviceAdded(mDevice);
|
||||
|
||||
verify(mCallback).onDeviceAdded(mDevice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchDeviceRemoved_registerCallback_shouldDispatchCallback() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
|
||||
mMediaManager.dispatchDeviceRemoved(mDevice);
|
||||
|
||||
verify(mCallback).onDeviceRemoved(mDevice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchDeviceListAdded_registerCallback_shouldDispatchCallback() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
|
||||
mMediaManager.dispatchDeviceListAdded();
|
||||
|
||||
verify(mCallback).onDeviceListAdded(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchDeviceListRemoved_registerCallback_shouldDispatchCallback() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
|
||||
mMediaManager.dispatchDeviceListRemoved(mMediaManager.mMediaDevices);
|
||||
|
||||
verify(mCallback).onDeviceListRemoved(mMediaManager.mMediaDevices);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchActiveDeviceChanged_registerCallback_shouldDispatchCallback() {
|
||||
mMediaManager.registerCallback(mCallback);
|
||||
|
||||
mMediaManager.dispatchConnectedDeviceChanged(TEST_ID);
|
||||
|
||||
verify(mCallback).onConnectedDeviceChanged(TEST_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMediaDevice_idExist_shouldReturnMediaDevice() {
|
||||
mMediaManager.mMediaDevices.add(mDevice);
|
||||
|
||||
final MediaDevice device = mMediaManager.findMediaDevice(TEST_ID);
|
||||
|
||||
assertThat(device.getId()).isEqualTo(mDevice.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMediaDevice_idNotExist_shouldReturnNull() {
|
||||
mMediaManager.mMediaDevices.add(mDevice);
|
||||
|
||||
final MediaDevice device = mMediaManager.findMediaDevice("123");
|
||||
|
||||
assertThat(device).isNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019 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.settingslib.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class PhoneMediaDeviceTest {
|
||||
|
||||
@Mock
|
||||
private LocalBluetoothProfileManager mLocalProfileManager;
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock
|
||||
private HearingAidProfile mHapProfile;
|
||||
@Mock
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private BluetoothDevice mDevice;
|
||||
|
||||
private Context mContext;
|
||||
private PhoneMediaDevice mPhoneMediaDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
|
||||
when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHapProfile);
|
||||
when(mA2dpProfile.getActiveDevice()).thenReturn(mDevice);
|
||||
|
||||
mPhoneMediaDevice = new PhoneMediaDevice(mContext, mLocalBluetoothManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_phoneDeviceSetActiveSuccess_isConnectedReturnTrue() {
|
||||
when(mA2dpProfile.setActiveDevice(null)).thenReturn(true);
|
||||
when(mHapProfile.setActiveDevice(null)).thenReturn(true);
|
||||
|
||||
assertThat(mPhoneMediaDevice.connect()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_a2dpProfileSetActiveFail_isConnectedReturnFalse() {
|
||||
when(mA2dpProfile.setActiveDevice(null)).thenReturn(false);
|
||||
when(mHapProfile.setActiveDevice(null)).thenReturn(true);
|
||||
|
||||
assertThat(mPhoneMediaDevice.connect()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_hearingAidProfileSetActiveFail_isConnectedReturnFalse() {
|
||||
when(mA2dpProfile.setActiveDevice(null)).thenReturn(true);
|
||||
when(mHapProfile.setActiveDevice(null)).thenReturn(false);
|
||||
|
||||
assertThat(mPhoneMediaDevice.connect()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_hearingAidAndA2dpProfileSetActiveFail_isConnectedReturnFalse() {
|
||||
when(mA2dpProfile.setActiveDevice(null)).thenReturn(false);
|
||||
when(mHapProfile.setActiveDevice(null)).thenReturn(false);
|
||||
|
||||
assertThat(mPhoneMediaDevice.connect()).isFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user