[LE Broadcast] Add the active LE device into broadcast when broadcasting
- Add the source into active sink device when user start the broadcasting. - Add a flag to avoid re-register callback of broadcast. - Register/Unregister the assistant's callback. Bug: 246761387 Test: local test Test: atest MediaOutputBroadcastDialogTest Change-Id: I7326a3d299943de2ede144f12d2b663c915dd304
This commit is contained in:
committed by
changbetty
parent
6e59a20333
commit
ad708d4d93
@@ -78,7 +78,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
private static final boolean DEBUG = true;
|
||||
private static final int HANDLE_BROADCAST_FAILED_DELAY = 3000;
|
||||
|
||||
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
protected final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
private final RecyclerView.LayoutManager mLayoutManager;
|
||||
|
||||
final Context mContext;
|
||||
@@ -102,11 +102,13 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
private int mListMaxHeight;
|
||||
private int mItemHeight;
|
||||
private WallpaperColors mWallpaperColors;
|
||||
private Executor mExecutor;
|
||||
private boolean mShouldLaunchLeBroadcastDialog;
|
||||
private boolean mIsLeBroadcastCallbackRegistered;
|
||||
|
||||
MediaOutputBaseAdapter mAdapter;
|
||||
|
||||
protected Executor mExecutor;
|
||||
|
||||
private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
|
||||
ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
|
||||
int totalItemsHeight = mAdapter.getItemCount() * mItemHeight;
|
||||
@@ -274,17 +276,19 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mMediaOutputController.start(this);
|
||||
if(isBroadcastSupported()) {
|
||||
mMediaOutputController.registerLeBroadcastServiceCallBack(mExecutor,
|
||||
if (isBroadcastSupported() && !mIsLeBroadcastCallbackRegistered) {
|
||||
mMediaOutputController.registerLeBroadcastServiceCallback(mExecutor,
|
||||
mBroadcastCallback);
|
||||
mIsLeBroadcastCallbackRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if(isBroadcastSupported()) {
|
||||
mMediaOutputController.unregisterLeBroadcastServiceCallBack(mBroadcastCallback);
|
||||
if (isBroadcastSupported() && mIsLeBroadcastCallbackRegistered) {
|
||||
mMediaOutputController.unregisterLeBroadcastServiceCallback(mBroadcastCallback);
|
||||
mIsLeBroadcastCallbackRegistered = false;
|
||||
}
|
||||
mMediaOutputController.stop();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
package com.android.systemui.media.dialog;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
@@ -34,8 +38,11 @@ import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
|
||||
import com.android.settingslib.media.BluetoothMediaDevice;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.settingslib.qrcode.QrCodeGenerator;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastSender;
|
||||
@@ -49,7 +56,7 @@ import com.google.zxing.WriterException;
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
private static final String TAG = "BroadcastDialog";
|
||||
private static final String TAG = "MediaOutputBroadcastDialog";
|
||||
|
||||
private ViewStub mBroadcastInfoArea;
|
||||
private ImageView mBroadcastQrCodeView;
|
||||
@@ -66,6 +73,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
private String mCurrentBroadcastName;
|
||||
private String mCurrentBroadcastCode;
|
||||
private boolean mIsStopbyUpdateBroadcastCode = false;
|
||||
|
||||
private TextWatcher mTextWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
@@ -105,6 +113,79 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
}
|
||||
};
|
||||
|
||||
private boolean mIsLeBroadcastAssistantCallbackRegistered;
|
||||
|
||||
private BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||
new BluetoothLeBroadcastAssistant.Callback() {
|
||||
@Override
|
||||
public void onSearchStarted(int reason) {
|
||||
Log.d(TAG, "Assistant-onSearchStarted: " + reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchStartFailed(int reason) {
|
||||
Log.d(TAG, "Assistant-onSearchStartFailed: " + reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchStopped(int reason) {
|
||||
Log.d(TAG, "Assistant-onSearchStopped: " + reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchStopFailed(int reason) {
|
||||
Log.d(TAG, "Assistant-onSearchStopFailed: " + reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {
|
||||
Log.d(TAG, "Assistant-onSourceFound:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceAdded: Device: " + sink
|
||||
+ ", sourceId: " + sourceId);
|
||||
mMainThreadHandler.post(() -> refreshUi());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceAddFailed(@NonNull BluetoothDevice sink,
|
||||
@NonNull BluetoothLeBroadcastMetadata source, int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceAddFailed: Device: " + sink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceModified(@NonNull BluetoothDevice sink, int sourceId,
|
||||
int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceModified:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceModifyFailed(@NonNull BluetoothDevice sink, int sourceId,
|
||||
int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceModifyFailed:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceRemoved(@NonNull BluetoothDevice sink, int sourceId,
|
||||
int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceRemoved:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceRemoveFailed(@NonNull BluetoothDevice sink, int sourceId,
|
||||
int reason) {
|
||||
Log.d(TAG, "Assistant-onSourceRemoveFailed:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveStateChanged(@NonNull BluetoothDevice sink, int sourceId,
|
||||
@NonNull BluetoothLeBroadcastReceiveState state) {
|
||||
Log.d(TAG, "Assistant-onReceiveStateChanged:");
|
||||
}
|
||||
};
|
||||
|
||||
static final int METADATA_BROADCAST_NAME = 0;
|
||||
static final int METADATA_BROADCAST_CODE = 1;
|
||||
|
||||
@@ -130,6 +211,27 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
initBtQrCodeUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
if (!mIsLeBroadcastAssistantCallbackRegistered) {
|
||||
mIsLeBroadcastAssistantCallbackRegistered = true;
|
||||
mMediaOutputController.registerLeBroadcastAssistantServiceCallback(mExecutor,
|
||||
mBroadcastAssistantCallback);
|
||||
}
|
||||
connectBroadcastWithActiveDevice();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (mIsLeBroadcastAssistantCallbackRegistered) {
|
||||
mIsLeBroadcastAssistantCallbackRegistered = false;
|
||||
mMediaOutputController.unregisterLeBroadcastAssistantServiceCallback(
|
||||
mBroadcastAssistantCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
int getHeaderIconRes() {
|
||||
return 0;
|
||||
@@ -224,6 +326,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
mCurrentBroadcastCode = getBroadcastMetadataInfo(METADATA_BROADCAST_CODE);
|
||||
mBroadcastName.setText(mCurrentBroadcastName);
|
||||
mBroadcastCode.setText(mCurrentBroadcastCode);
|
||||
refresh(false);
|
||||
}
|
||||
|
||||
private void inflateBroadcastInfoArea() {
|
||||
@@ -233,7 +336,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
|
||||
private void setQrCodeView() {
|
||||
//get the Metadata, and convert to BT QR code format.
|
||||
String broadcastMetadata = getBroadcastMetadata();
|
||||
String broadcastMetadata = getLocalBroadcastMetadataQrCodeString();
|
||||
if (broadcastMetadata.isEmpty()) {
|
||||
//TDOD(b/226708424) Error handling for unable to generate the QR code bitmap
|
||||
return;
|
||||
@@ -249,6 +352,33 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
}
|
||||
}
|
||||
|
||||
void connectBroadcastWithActiveDevice() {
|
||||
//get the Metadata, and convert to BT QR code format.
|
||||
BluetoothLeBroadcastMetadata broadcastMetadata = getBroadcastMetadata();
|
||||
if (broadcastMetadata == null) {
|
||||
Log.e(TAG, "Error: There is no broadcastMetadata.");
|
||||
return;
|
||||
}
|
||||
MediaDevice mediaDevice = mMediaOutputController.getCurrentConnectedMediaDevice();
|
||||
if (mediaDevice == null || !(mediaDevice instanceof BluetoothMediaDevice)
|
||||
|| !mediaDevice.isBLEDevice()) {
|
||||
Log.e(TAG, "Error: There is no active BT LE device.");
|
||||
return;
|
||||
}
|
||||
BluetoothDevice sink = ((BluetoothMediaDevice) mediaDevice).getCachedDevice().getDevice();
|
||||
Log.d(TAG, "The broadcastMetadata broadcastId: " + broadcastMetadata.getBroadcastId()
|
||||
+ ", the device: " + sink.getAnonymizedAddress());
|
||||
|
||||
if (mMediaOutputController.isThereAnyBroadcastSourceIntoSinkDevice(sink)) {
|
||||
Log.d(TAG, "The sink device has the broadcast source now.");
|
||||
return;
|
||||
}
|
||||
if (!mMediaOutputController.addSourceIntoSinkDeviceWithBluetoothLeAssistant(sink,
|
||||
broadcastMetadata, /*isGroupOp=*/ true)) {
|
||||
Log.e(TAG, "Error: Source add failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBroadcastCodeVisibility() {
|
||||
mBroadcastCode.setTransformationMethod(
|
||||
mIsPasswordHide ? HideReturnsTransformationMethod.getInstance()
|
||||
@@ -282,7 +412,11 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
mAlertDialog.show();
|
||||
}
|
||||
|
||||
private String getBroadcastMetadata() {
|
||||
private String getLocalBroadcastMetadataQrCodeString() {
|
||||
return mMediaOutputController.getLocalBroadcastMetadataQrCodeString();
|
||||
}
|
||||
|
||||
private BluetoothLeBroadcastMetadata getBroadcastMetadata() {
|
||||
return mMediaOutputController.getBroadcastMetadata();
|
||||
}
|
||||
|
||||
@@ -313,6 +447,17 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBroadcastSupported() {
|
||||
boolean isBluetoothLeDevice = false;
|
||||
if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) {
|
||||
isBluetoothLeDevice = mMediaOutputController.isBluetoothLeDevice(
|
||||
mMediaOutputController.getCurrentConnectedMediaDevice());
|
||||
}
|
||||
|
||||
return mMediaOutputController.isBroadcastSupported() && isBluetoothLeDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLeBroadcastStarted() {
|
||||
mRetryCount = 0;
|
||||
@@ -332,6 +477,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
|
||||
@Override
|
||||
public void handleLeBroadcastMetadataChanged() {
|
||||
Log.d(TAG, "handleLeBroadcastMetadataChanged:");
|
||||
refreshUi();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ import android.app.AlertDialog;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.Notification;
|
||||
import android.app.WallpaperColors;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcast;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -66,6 +70,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.media.InfoMediaManager;
|
||||
@@ -1050,7 +1055,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
ALLOWLIST_DURATION_MS);
|
||||
}
|
||||
|
||||
String getBroadcastMetadata() {
|
||||
String getLocalBroadcastMetadataQrCodeString() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
@@ -1062,6 +1067,17 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
return metadata != null ? metadata.convertToQrCodeString() : "";
|
||||
}
|
||||
|
||||
BluetoothLeBroadcastMetadata getBroadcastMetadata() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
Log.d(TAG, "getBroadcastMetadata: LE Audio Broadcast is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
return broadcast.getLatestBluetoothLeBroadcastMetadata();
|
||||
}
|
||||
|
||||
boolean isActiveRemoteDevice(@NonNull MediaDevice device) {
|
||||
final List<String> features = device.getFeatures();
|
||||
return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
|
||||
@@ -1122,7 +1138,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
return true;
|
||||
}
|
||||
|
||||
void registerLeBroadcastServiceCallBack(
|
||||
void registerLeBroadcastServiceCallback(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
@@ -1131,10 +1147,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Register LE broadcast callback");
|
||||
broadcast.registerServiceCallBack(executor, callback);
|
||||
}
|
||||
|
||||
void unregisterLeBroadcastServiceCallBack(
|
||||
void unregisterLeBroadcastServiceCallback(
|
||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
@@ -1142,9 +1159,59 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Unregister LE broadcast callback");
|
||||
broadcast.unregisterServiceCallBack(callback);
|
||||
}
|
||||
|
||||
boolean isThereAnyBroadcastSourceIntoSinkDevice(BluetoothDevice sink) {
|
||||
LocalBluetoothLeBroadcastAssistant assistant =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
|
||||
if (assistant == null) {
|
||||
Log.d(TAG, "The broadcast assistant profile is null");
|
||||
return false;
|
||||
}
|
||||
List<BluetoothLeBroadcastReceiveState> sourceList = assistant.getAllSources(sink);
|
||||
Log.d(TAG, "isThereAnyBroadcastSourceIntoSinkDevice: List size: " + sourceList.size());
|
||||
return !sourceList.isEmpty();
|
||||
}
|
||||
|
||||
boolean addSourceIntoSinkDeviceWithBluetoothLeAssistant(BluetoothDevice sink,
|
||||
BluetoothLeBroadcastMetadata metadata, boolean isGroupOp) {
|
||||
LocalBluetoothLeBroadcastAssistant assistant =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
|
||||
if (assistant == null) {
|
||||
Log.d(TAG, "The broadcast assistant profile is null");
|
||||
return false;
|
||||
}
|
||||
assistant.addSource(sink, metadata, isGroupOp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void registerLeBroadcastAssistantServiceCallback(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BluetoothLeBroadcastAssistant.Callback callback) {
|
||||
LocalBluetoothLeBroadcastAssistant assistant =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
|
||||
if (assistant == null) {
|
||||
Log.d(TAG, "The broadcast assistant profile is null");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Register LE broadcast assistant callback");
|
||||
assistant.registerServiceCallBack(executor, callback);
|
||||
}
|
||||
|
||||
void unregisterLeBroadcastAssistantServiceCallback(
|
||||
@NonNull BluetoothLeBroadcastAssistant.Callback callback) {
|
||||
LocalBluetoothLeBroadcastAssistant assistant =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
|
||||
if (assistant == null) {
|
||||
Log.d(TAG, "The broadcast assistant profile is null");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Unregister LE broadcast assistant callback");
|
||||
assistant.unregisterServiceCallBack(callback);
|
||||
}
|
||||
|
||||
private boolean isPlayBackInfoLocal() {
|
||||
return mMediaController != null
|
||||
&& mMediaController.getPlaybackInfo() != null
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.systemui.media.dialog;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.media.AudioManager;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.os.PowerExemptionManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.settingslib.media.BluetoothMediaDevice;
|
||||
import com.android.settingslib.media.LocalMediaManager;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||
import com.android.systemui.broadcast.BroadcastSender;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class MediaOutputBroadcastDialogTest extends SysuiTestCase {
|
||||
|
||||
private static final String TEST_PACKAGE = "test_package";
|
||||
|
||||
// Mock
|
||||
private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
|
||||
private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
|
||||
private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
|
||||
LocalBluetoothProfileManager.class);
|
||||
private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
|
||||
LocalBluetoothLeBroadcast.class);
|
||||
private final LocalBluetoothLeBroadcastAssistant mLocalBluetoothLeBroadcastAssistant = mock(
|
||||
LocalBluetoothLeBroadcastAssistant.class);
|
||||
private final BluetoothLeBroadcastMetadata mBluetoothLeBroadcastMetadata = mock(
|
||||
BluetoothLeBroadcastMetadata.class);
|
||||
private final BluetoothLeBroadcastReceiveState mBluetoothLeBroadcastReceiveState = mock(
|
||||
BluetoothLeBroadcastReceiveState.class);
|
||||
private final ActivityStarter mStarter = mock(ActivityStarter.class);
|
||||
private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
|
||||
private final LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
|
||||
private final MediaDevice mBluetoothMediaDevice = mock(BluetoothMediaDevice.class);
|
||||
private final BluetoothDevice mBluetoothDevice = mock(BluetoothDevice.class);
|
||||
private final CachedBluetoothDevice mCachedBluetoothDevice = mock(CachedBluetoothDevice.class);
|
||||
private final CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
|
||||
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
|
||||
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
|
||||
NearbyMediaDevicesManager.class);
|
||||
private final AudioManager mAudioManager = mock(AudioManager.class);
|
||||
private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
|
||||
private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
|
||||
private FeatureFlags mFlags = mock(FeatureFlags.class);
|
||||
|
||||
private MediaOutputBroadcastDialog mMediaOutputBroadcastDialog;
|
||||
private MediaOutputController mMediaOutputController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(null);
|
||||
|
||||
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
|
||||
mMediaSessionManager, mLocalBluetoothManager, mStarter,
|
||||
mNotifCollection, mDialogLaunchAnimator,
|
||||
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
|
||||
mKeyguardManager, mFlags);
|
||||
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
|
||||
mMediaOutputBroadcastDialog = new MediaOutputBroadcastDialog(mContext, false,
|
||||
mBroadcastSender, mMediaOutputController);
|
||||
mMediaOutputBroadcastDialog.show();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mMediaOutputBroadcastDialog.dismissDialog();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectBroadcastWithActiveDevice_noBroadcastMetadata_failToAddSource() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
when(mLocalBluetoothLeBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(null);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcastAssistant);
|
||||
|
||||
mMediaOutputBroadcastDialog.connectBroadcastWithActiveDevice();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcastAssistant, never()).addSource(any(), any(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectBroadcastWithActiveDevice_noConnectedMediaDevice_failToAddSource() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
when(mLocalBluetoothLeBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(
|
||||
mBluetoothLeBroadcastMetadata);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcastAssistant);
|
||||
when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(null);
|
||||
|
||||
mMediaOutputBroadcastDialog.connectBroadcastWithActiveDevice();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcastAssistant, never()).addSource(any(), any(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectBroadcastWithActiveDevice_hasBroadcastSource_failToAddSource() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
when(mLocalBluetoothLeBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(
|
||||
mBluetoothLeBroadcastMetadata);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcastAssistant);
|
||||
when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mBluetoothMediaDevice);
|
||||
when(((BluetoothMediaDevice) mBluetoothMediaDevice).getCachedDevice())
|
||||
.thenReturn(mCachedBluetoothDevice);
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
|
||||
sourceList.add(mBluetoothLeBroadcastReceiveState);
|
||||
when(mLocalBluetoothLeBroadcastAssistant.getAllSources(mBluetoothDevice)).thenReturn(
|
||||
sourceList);
|
||||
|
||||
mMediaOutputBroadcastDialog.connectBroadcastWithActiveDevice();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcastAssistant, never()).addSource(any(), any(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectBroadcastWithActiveDevice_noBroadcastSource_failToAddSource() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcastAssistant);
|
||||
when(mLocalBluetoothLeBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(
|
||||
mBluetoothLeBroadcastMetadata);
|
||||
when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mBluetoothMediaDevice);
|
||||
when(mBluetoothMediaDevice.isBLEDevice()).thenReturn(true);
|
||||
when(((BluetoothMediaDevice) mBluetoothMediaDevice).getCachedDevice()).thenReturn(
|
||||
mCachedBluetoothDevice);
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
|
||||
when(mLocalBluetoothLeBroadcastAssistant.getAllSources(mBluetoothDevice)).thenReturn(
|
||||
sourceList);
|
||||
|
||||
mMediaOutputBroadcastDialog.connectBroadcastWithActiveDevice();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcastAssistant, times(1)).addSource(any(), any(), anyBoolean());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user