Merge "[LE Broadcast] Add the active LE device into broadcast when broadcasting" into udc-dev
This commit is contained in:
@@ -78,7 +78,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
|||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = true;
|
||||||
private static final int HANDLE_BROADCAST_FAILED_DELAY = 3000;
|
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;
|
private final RecyclerView.LayoutManager mLayoutManager;
|
||||||
|
|
||||||
final Context mContext;
|
final Context mContext;
|
||||||
@@ -102,11 +102,13 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
|||||||
private int mListMaxHeight;
|
private int mListMaxHeight;
|
||||||
private int mItemHeight;
|
private int mItemHeight;
|
||||||
private WallpaperColors mWallpaperColors;
|
private WallpaperColors mWallpaperColors;
|
||||||
private Executor mExecutor;
|
|
||||||
private boolean mShouldLaunchLeBroadcastDialog;
|
private boolean mShouldLaunchLeBroadcastDialog;
|
||||||
|
private boolean mIsLeBroadcastCallbackRegistered;
|
||||||
|
|
||||||
MediaOutputBaseAdapter mAdapter;
|
MediaOutputBaseAdapter mAdapter;
|
||||||
|
|
||||||
|
protected Executor mExecutor;
|
||||||
|
|
||||||
private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
|
private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
|
||||||
ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
|
ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
|
||||||
int totalItemsHeight = mAdapter.getItemCount() * mItemHeight;
|
int totalItemsHeight = mAdapter.getItemCount() * mItemHeight;
|
||||||
@@ -274,17 +276,19 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
mMediaOutputController.start(this);
|
mMediaOutputController.start(this);
|
||||||
if(isBroadcastSupported()) {
|
if (isBroadcastSupported() && !mIsLeBroadcastCallbackRegistered) {
|
||||||
mMediaOutputController.registerLeBroadcastServiceCallBack(mExecutor,
|
mMediaOutputController.registerLeBroadcastServiceCallback(mExecutor,
|
||||||
mBroadcastCallback);
|
mBroadcastCallback);
|
||||||
|
mIsLeBroadcastCallbackRegistered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
if(isBroadcastSupported()) {
|
if (isBroadcastSupported() && mIsLeBroadcastCallbackRegistered) {
|
||||||
mMediaOutputController.unregisterLeBroadcastServiceCallBack(mBroadcastCallback);
|
mMediaOutputController.unregisterLeBroadcastServiceCallback(mBroadcastCallback);
|
||||||
|
mIsLeBroadcastCallbackRegistered = false;
|
||||||
}
|
}
|
||||||
mMediaOutputController.stop();
|
mMediaOutputController.stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
package com.android.systemui.media.dialog;
|
package com.android.systemui.media.dialog;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
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.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -34,8 +38,11 @@ import android.widget.EditText;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
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.settingslib.qrcode.QrCodeGenerator;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.broadcast.BroadcastSender;
|
import com.android.systemui.broadcast.BroadcastSender;
|
||||||
@@ -49,7 +56,7 @@ import com.google.zxing.WriterException;
|
|||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||||
private static final String TAG = "BroadcastDialog";
|
private static final String TAG = "MediaOutputBroadcastDialog";
|
||||||
|
|
||||||
private ViewStub mBroadcastInfoArea;
|
private ViewStub mBroadcastInfoArea;
|
||||||
private ImageView mBroadcastQrCodeView;
|
private ImageView mBroadcastQrCodeView;
|
||||||
@@ -66,6 +73,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
private String mCurrentBroadcastName;
|
private String mCurrentBroadcastName;
|
||||||
private String mCurrentBroadcastCode;
|
private String mCurrentBroadcastCode;
|
||||||
private boolean mIsStopbyUpdateBroadcastCode = false;
|
private boolean mIsStopbyUpdateBroadcastCode = false;
|
||||||
|
|
||||||
private TextWatcher mTextWatcher = new TextWatcher() {
|
private TextWatcher mTextWatcher = new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
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_NAME = 0;
|
||||||
static final int METADATA_BROADCAST_CODE = 1;
|
static final int METADATA_BROADCAST_CODE = 1;
|
||||||
|
|
||||||
@@ -130,6 +211,27 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
initBtQrCodeUI();
|
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
|
@Override
|
||||||
int getHeaderIconRes() {
|
int getHeaderIconRes() {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -224,6 +326,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
mCurrentBroadcastCode = getBroadcastMetadataInfo(METADATA_BROADCAST_CODE);
|
mCurrentBroadcastCode = getBroadcastMetadataInfo(METADATA_BROADCAST_CODE);
|
||||||
mBroadcastName.setText(mCurrentBroadcastName);
|
mBroadcastName.setText(mCurrentBroadcastName);
|
||||||
mBroadcastCode.setText(mCurrentBroadcastCode);
|
mBroadcastCode.setText(mCurrentBroadcastCode);
|
||||||
|
refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void inflateBroadcastInfoArea() {
|
private void inflateBroadcastInfoArea() {
|
||||||
@@ -233,7 +336,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
|
|
||||||
private void setQrCodeView() {
|
private void setQrCodeView() {
|
||||||
//get the Metadata, and convert to BT QR code format.
|
//get the Metadata, and convert to BT QR code format.
|
||||||
String broadcastMetadata = getBroadcastMetadata();
|
String broadcastMetadata = getLocalBroadcastMetadataQrCodeString();
|
||||||
if (broadcastMetadata.isEmpty()) {
|
if (broadcastMetadata.isEmpty()) {
|
||||||
//TDOD(b/226708424) Error handling for unable to generate the QR code bitmap
|
//TDOD(b/226708424) Error handling for unable to generate the QR code bitmap
|
||||||
return;
|
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() {
|
private void updateBroadcastCodeVisibility() {
|
||||||
mBroadcastCode.setTransformationMethod(
|
mBroadcastCode.setTransformationMethod(
|
||||||
mIsPasswordHide ? HideReturnsTransformationMethod.getInstance()
|
mIsPasswordHide ? HideReturnsTransformationMethod.getInstance()
|
||||||
@@ -282,7 +412,11 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
mAlertDialog.show();
|
mAlertDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getBroadcastMetadata() {
|
private String getLocalBroadcastMetadataQrCodeString() {
|
||||||
|
return mMediaOutputController.getLocalBroadcastMetadataQrCodeString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BluetoothLeBroadcastMetadata getBroadcastMetadata() {
|
||||||
return mMediaOutputController.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
|
@Override
|
||||||
public void handleLeBroadcastStarted() {
|
public void handleLeBroadcastStarted() {
|
||||||
mRetryCount = 0;
|
mRetryCount = 0;
|
||||||
@@ -332,6 +477,7 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleLeBroadcastMetadataChanged() {
|
public void handleLeBroadcastMetadataChanged() {
|
||||||
|
Log.d(TAG, "handleLeBroadcastMetadataChanged:");
|
||||||
refreshUi();
|
refreshUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ import android.app.AlertDialog;
|
|||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.WallpaperColors;
|
import android.app.WallpaperColors;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothLeBroadcast;
|
import android.bluetooth.BluetoothLeBroadcast;
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@@ -66,6 +70,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
|
|||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.settingslib.media.InfoMediaManager;
|
import com.android.settingslib.media.InfoMediaManager;
|
||||||
@@ -1049,7 +1054,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
ALLOWLIST_DURATION_MS);
|
ALLOWLIST_DURATION_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getBroadcastMetadata() {
|
String getLocalBroadcastMetadataQrCodeString() {
|
||||||
LocalBluetoothLeBroadcast broadcast =
|
LocalBluetoothLeBroadcast broadcast =
|
||||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||||
if (broadcast == null) {
|
if (broadcast == null) {
|
||||||
@@ -1061,6 +1066,17 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
return metadata != null ? metadata.convertToQrCodeString() : "";
|
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) {
|
boolean isActiveRemoteDevice(@NonNull MediaDevice device) {
|
||||||
final List<String> features = device.getFeatures();
|
final List<String> features = device.getFeatures();
|
||||||
return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
|
return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
|
||||||
@@ -1121,7 +1137,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerLeBroadcastServiceCallBack(
|
void registerLeBroadcastServiceCallback(
|
||||||
@NonNull @CallbackExecutor Executor executor,
|
@NonNull @CallbackExecutor Executor executor,
|
||||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||||
LocalBluetoothLeBroadcast broadcast =
|
LocalBluetoothLeBroadcast broadcast =
|
||||||
@@ -1130,10 +1146,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
Log.d(TAG, "The broadcast profile is null");
|
Log.d(TAG, "The broadcast profile is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Log.d(TAG, "Register LE broadcast callback");
|
||||||
broadcast.registerServiceCallBack(executor, callback);
|
broadcast.registerServiceCallBack(executor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterLeBroadcastServiceCallBack(
|
void unregisterLeBroadcastServiceCallback(
|
||||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||||
LocalBluetoothLeBroadcast broadcast =
|
LocalBluetoothLeBroadcast broadcast =
|
||||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||||
@@ -1141,9 +1158,59 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
Log.d(TAG, "The broadcast profile is null");
|
Log.d(TAG, "The broadcast profile is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Log.d(TAG, "Unregister LE broadcast callback");
|
||||||
broadcast.unregisterServiceCallBack(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() {
|
private boolean isPlayBackInfoLocal() {
|
||||||
return mMediaController != null
|
return mMediaController != null
|
||||||
&& mMediaController.getPlaybackInfo() != 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