[LE_Broadcast]Start broadcast and stop broadcast
- Add start broadcast UI and stop broadcast UI - Add broadcast start process - Add broadcast stop process Bug: 227511707 Test: build pass and manaual test. atest MediaOutputBaseDialogTest (PASS) atest MediaOutputDialogTest (PASS) Change-Id: Idd26d2b4e10dfcd00045184ddd2f9815a02ec7ce
This commit is contained in:
@@ -2283,6 +2283,10 @@
|
||||
<string name="media_output_broadcast_code">Password</string>
|
||||
<!-- Button for change broadcast name and broadcast code [CHAR LIMIT=60] -->
|
||||
<string name="media_output_broadcast_dialog_save">Save</string>
|
||||
<!-- The "starting" text when Broadcast is starting [CHAR LIMIT=60] -->
|
||||
<string name="media_output_broadcast_starting">Starting…</string>
|
||||
<!-- The button text when Broadcast start failed [CHAR LIMIT=60] -->
|
||||
<string name="media_output_broadcast_start_failed">Can\u2019t broadcast</string>
|
||||
|
||||
<!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
|
||||
<string name="build_number_clip_data_label">Build number</string>
|
||||
|
||||
@@ -19,7 +19,10 @@ package com.android.systemui.media.dialog;
|
||||
import static android.view.WindowInsets.Type.navigationBars;
|
||||
import static android.view.WindowInsets.Type.statusBars;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.WallpaperColors;
|
||||
import android.bluetooth.BluetoothLeBroadcast;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
@@ -59,6 +62,9 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastSender;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Base dialog for media output UI
|
||||
*/
|
||||
@@ -69,6 +75,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
private static final String EMPTY_TITLE = " ";
|
||||
private static final String PREF_NAME = "MediaOutputDialog";
|
||||
private static final String PREF_IS_LE_BROADCAST_FIRST_LAUNCH = "PrefIsLeBroadcastFirstLaunch";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
private final RecyclerView.LayoutManager mLayoutManager;
|
||||
@@ -91,6 +98,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
private Button mAppButton;
|
||||
private int mListMaxHeight;
|
||||
private WallpaperColors mWallpaperColors;
|
||||
private Executor mExecutor;
|
||||
|
||||
MediaOutputBaseAdapter mAdapter;
|
||||
|
||||
@@ -103,6 +111,79 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
}
|
||||
};
|
||||
|
||||
private final BluetoothLeBroadcast.Callback mBroadcastCallback =
|
||||
new BluetoothLeBroadcast.Callback() {
|
||||
@Override
|
||||
public void onBroadcastStarted(int reason, int broadcastId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastStarted(), reason = " + reason
|
||||
+ ", broadcastId = " + broadcastId);
|
||||
}
|
||||
mMainThreadHandler.post(() -> startLeBroadcastDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastStartFailed(int reason) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
|
||||
}
|
||||
handleLeBroadcastStartFailed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastMetadataChanged(int broadcastId,
|
||||
@NonNull BluetoothLeBroadcastMetadata metadata) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId
|
||||
+ ", metadata = " + metadata);
|
||||
}
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastStopped(int reason, int broadcastId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastStopped(), reason = " + reason
|
||||
+ ", broadcastId = " + broadcastId);
|
||||
}
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastStopFailed(int reason) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
|
||||
}
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastUpdated(int reason, int broadcastId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastUpdated(), reason = " + reason
|
||||
+ ", broadcastId = " + broadcastId);
|
||||
}
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastUpdateFailed(int reason, int broadcastId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBroadcastUpdateFailed(), reason = " + reason
|
||||
+ ", broadcastId = " + broadcastId);
|
||||
}
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackStarted(int reason, int broadcastId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackStopped(int reason, int broadcastId) {
|
||||
}
|
||||
};
|
||||
|
||||
public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender,
|
||||
MediaOutputController mediaOutputController) {
|
||||
super(context, R.style.Theme_SystemUI_Dialog_Media);
|
||||
@@ -114,6 +195,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
mLayoutManager = new LinearLayoutManager(mContext);
|
||||
mListMaxHeight = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.media_output_dialog_list_max_height);
|
||||
mExecutor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,11 +253,18 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mMediaOutputController.start(this);
|
||||
if(isBroadcastSupported()) {
|
||||
mMediaOutputController.registerLeBroadcastServiceCallBack(mExecutor,
|
||||
mBroadcastCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if(isBroadcastSupported()) {
|
||||
mMediaOutputController.unregisterLeBroadcastServiceCallBack(mBroadcastCallback);
|
||||
}
|
||||
mMediaOutputController.stop();
|
||||
}
|
||||
|
||||
@@ -254,35 +343,12 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
// Show when remote media session is available
|
||||
// Show when remote media session is available or
|
||||
// when the device supports BT LE audio + media is playing
|
||||
mStopButton.setVisibility(getStopButtonVisibility());
|
||||
if (isBroadcastSupported() && mMediaOutputController.isPlaying()) {
|
||||
mStopButton.setText(R.string.media_output_broadcast);
|
||||
mStopButton.setOnClickListener(v -> {
|
||||
SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
|
||||
if (sharedPref != null
|
||||
&& sharedPref.getBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, true)) {
|
||||
Log.d(TAG, "PREF_IS_LE_BROADCAST_FIRST_LAUNCH: true");
|
||||
|
||||
mMediaOutputController.launchLeBroadcastNotifyDialog(mDialogView,
|
||||
mBroadcastSender,
|
||||
MediaOutputController.BroadcastNotifyDialog.ACTION_FIRST_LAUNCH);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, false);
|
||||
editor.apply();
|
||||
} else {
|
||||
mMediaOutputController.launchMediaOutputBroadcastDialog(mDialogView,
|
||||
mBroadcastSender);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mStopButton.setOnClickListener(v -> {
|
||||
mMediaOutputController.releaseSession();
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
mStopButton.setEnabled(true);
|
||||
mStopButton.setText(getStopButtonText());
|
||||
mStopButton.setOnClickListener(v -> onStopButtonClick());
|
||||
}
|
||||
|
||||
private Drawable resizeDrawable(Drawable drawable, int size) {
|
||||
@@ -301,6 +367,56 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
Bitmap.createScaledBitmap(bitmap, size, size, false));
|
||||
}
|
||||
|
||||
protected void handleLeBroadcastStartFailed() {
|
||||
mStopButton.setText(R.string.media_output_broadcast_start_failed);
|
||||
mStopButton.setEnabled(false);
|
||||
mMainThreadHandler.postDelayed(() -> refresh(), 3000);
|
||||
}
|
||||
|
||||
protected void startLeBroadcast() {
|
||||
mStopButton.setText(R.string.media_output_broadcast_starting);
|
||||
mStopButton.setEnabled(false);
|
||||
if (!mMediaOutputController.startBluetoothLeBroadcast()) {
|
||||
// If the system can't execute "broadcast start", then UI shows the error.
|
||||
handleLeBroadcastStartFailed();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean startLeBroadcastDialogForFirstTime(){
|
||||
SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
if (sharedPref != null
|
||||
&& sharedPref.getBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, true)) {
|
||||
Log.d(TAG, "PREF_IS_LE_BROADCAST_FIRST_LAUNCH: true");
|
||||
|
||||
mMediaOutputController.launchLeBroadcastNotifyDialog(mDialogView,
|
||||
mBroadcastSender,
|
||||
MediaOutputController.BroadcastNotifyDialog.ACTION_FIRST_LAUNCH,
|
||||
(d, w) -> {
|
||||
startLeBroadcast();
|
||||
});
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, false);
|
||||
editor.apply();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void startLeBroadcastDialog() {
|
||||
mMediaOutputController.launchMediaOutputBroadcastDialog(mDialogView,
|
||||
mBroadcastSender);
|
||||
refresh();
|
||||
}
|
||||
|
||||
protected void stopLeBroadcast() {
|
||||
mStopButton.setEnabled(false);
|
||||
if (!mMediaOutputController.stopBluetoothLeBroadcast()) {
|
||||
// If the system can't execute "broadcast stop", then UI does refresh.
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
}
|
||||
|
||||
abstract Drawable getAppSourceIcon();
|
||||
|
||||
abstract int getHeaderIconRes();
|
||||
@@ -315,6 +431,15 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
|
||||
abstract int getStopButtonVisibility();
|
||||
|
||||
public CharSequence getStopButtonText() {
|
||||
return mContext.getText(R.string.keyboard_key_media_stop);
|
||||
}
|
||||
|
||||
public void onStopButtonClick() {
|
||||
mMediaOutputController.releaseSession();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
public boolean isBroadcastSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -142,8 +142,11 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog {
|
||||
|
||||
mBroadcastNotify = getDialogView().requireViewById(R.id.broadcast_info);
|
||||
mBroadcastNotify.setOnClickListener(v -> {
|
||||
mMediaOutputController.launchLeBroadcastNotifyDialog(null, null,
|
||||
MediaOutputController.BroadcastNotifyDialog.ACTION_BROADCAST_INFO_ICON);
|
||||
mMediaOutputController.launchLeBroadcastNotifyDialog(
|
||||
/* view= */ null,
|
||||
/* broadcastSender= */ null,
|
||||
MediaOutputController.BroadcastNotifyDialog.ACTION_BROADCAST_INFO_ICON,
|
||||
/* onClickListener= */ null);
|
||||
});
|
||||
mBroadcastName = getDialogView().requireViewById(R.id.broadcast_name_summary);
|
||||
mBroadcastNameEdit = getDialogView().requireViewById(R.id.broadcast_name_edit);
|
||||
|
||||
@@ -18,10 +18,13 @@ package com.android.systemui.media.dialog;
|
||||
|
||||
import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Notification;
|
||||
import android.app.WallpaperColors;
|
||||
import android.bluetooth.BluetoothLeBroadcast;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -58,7 +61,7 @@ import androidx.mediarouter.media.MediaRouterParams;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.media.BluetoothMediaDevice;
|
||||
import com.android.settingslib.media.InfoMediaManager;
|
||||
@@ -83,6 +86,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -642,17 +646,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
}
|
||||
|
||||
void launchLeBroadcastNotifyDialog(View mediaOutputDialog, BroadcastSender broadcastSender,
|
||||
BroadcastNotifyDialog action) {
|
||||
BroadcastNotifyDialog action, final DialogInterface.OnClickListener listener) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
switch (action) {
|
||||
case ACTION_FIRST_LAUNCH:
|
||||
builder.setTitle(R.string.media_output_first_broadcast_title);
|
||||
builder.setMessage(R.string.media_output_first_notify_broadcast_message);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.setPositiveButton(R.string.media_output_broadcast,
|
||||
(d, w) -> {
|
||||
launchMediaOutputBroadcastDialog(mediaOutputDialog, broadcastSender);
|
||||
});
|
||||
builder.setPositiveButton(R.string.media_output_broadcast, listener);
|
||||
break;
|
||||
case ACTION_BROADCAST_INFO_ICON:
|
||||
builder.setTitle(R.string.media_output_broadcast);
|
||||
@@ -685,18 +686,64 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
|| features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
|
||||
}
|
||||
|
||||
boolean isBluetoothLeDevice(@NonNull MediaDevice device) {
|
||||
if (device instanceof BluetoothMediaDevice) {
|
||||
final CachedBluetoothDevice cachedDevice =
|
||||
((BluetoothMediaDevice) device).getCachedDevice();
|
||||
boolean isConnectedLeAudioDevice =
|
||||
(cachedDevice != null) ? cachedDevice.isConnectedLeAudioDevice() : false;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "isConnectedLeAudioDevice=" + isConnectedLeAudioDevice);
|
||||
}
|
||||
return isConnectedLeAudioDevice;
|
||||
boolean isBroadcastSupported() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
return broadcast != null ? true : false;
|
||||
}
|
||||
|
||||
boolean isBluetoothLeBroadcastEnabled() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return broadcast.isEnabled(null);
|
||||
}
|
||||
|
||||
boolean startBluetoothLeBroadcast() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return false;
|
||||
}
|
||||
broadcast.startBroadcast(getAppSourceName(), /*language*/ null);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean stopBluetoothLeBroadcast() {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return false;
|
||||
}
|
||||
broadcast.stopLatestBroadcast();
|
||||
return true;
|
||||
}
|
||||
|
||||
void registerLeBroadcastServiceCallBack(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return;
|
||||
}
|
||||
broadcast.registerServiceCallBack(executor, callback);
|
||||
}
|
||||
|
||||
void unregisterLeBroadcastServiceCallBack(
|
||||
@NonNull BluetoothLeBroadcast.Callback callback) {
|
||||
LocalBluetoothLeBroadcast broadcast =
|
||||
mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
|
||||
if (broadcast == null) {
|
||||
Log.d(TAG, "The broadcast profile is null");
|
||||
return;
|
||||
}
|
||||
broadcast.unregisterServiceCallBack(callback);
|
||||
}
|
||||
|
||||
private boolean isPlayBackInfoLocal() {
|
||||
|
||||
@@ -27,7 +27,6 @@ import androidx.core.graphics.drawable.IconCompat;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.UiEvent;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastSender;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
@@ -93,18 +92,41 @@ public class MediaOutputDialog extends MediaOutputBaseDialog {
|
||||
isActiveRemoteDevice = mMediaOutputController.isActiveRemoteDevice(
|
||||
mMediaOutputController.getCurrentConnectedMediaDevice());
|
||||
}
|
||||
boolean isBroadCastSupported = isBroadcastSupported();
|
||||
boolean showBroadcastButton = isBroadcastSupported() && mMediaOutputController.isPlaying();
|
||||
|
||||
return (isActiveRemoteDevice || isBroadCastSupported) ? View.VISIBLE : View.GONE;
|
||||
return (isActiveRemoteDevice || showBroadcastButton) ? View.VISIBLE : View.GONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBroadcastSupported() {
|
||||
MediaDevice device = mMediaOutputController.getCurrentConnectedMediaDevice();
|
||||
if (device == null) {
|
||||
return false;
|
||||
return mMediaOutputController.isBroadcastSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getStopButtonText() {
|
||||
int resId = R.string.keyboard_key_media_stop;
|
||||
if (isBroadcastSupported() && mMediaOutputController.isPlaying()
|
||||
&& !mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
|
||||
resId = R.string.media_output_broadcast;
|
||||
}
|
||||
return mContext.getText(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopButtonClick() {
|
||||
if (isBroadcastSupported() && mMediaOutputController.isPlaying()) {
|
||||
if (!mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
|
||||
if (startLeBroadcastDialogForFirstTime()) {
|
||||
return;
|
||||
}
|
||||
startLeBroadcast();
|
||||
} else {
|
||||
stopLeBroadcast();
|
||||
}
|
||||
} else {
|
||||
mMediaOutputController.releaseSession();
|
||||
dismiss();
|
||||
}
|
||||
return mMediaOutputController.isBluetoothLeDevice(device);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.media.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -26,18 +27,23 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.os.Bundle;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||
@@ -50,6 +56,8 @@ 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
|
||||
@@ -61,8 +69,14 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
|
||||
|
||||
// Mock
|
||||
private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class);
|
||||
private MediaController mMediaController = mock(MediaController.class);
|
||||
private PlaybackState mPlaybackState = mock(PlaybackState.class);
|
||||
private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
|
||||
private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
|
||||
private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
|
||||
LocalBluetoothProfileManager.class);
|
||||
private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
|
||||
LocalBluetoothLeBroadcast.class);
|
||||
private ActivityStarter mStarter = mock(ActivityStarter.class);
|
||||
private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
|
||||
private NotificationEntryManager mNotificationEntryManager =
|
||||
@@ -71,15 +85,26 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
|
||||
NearbyMediaDevicesManager.class);
|
||||
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
|
||||
|
||||
private List<MediaController> mMediaControllers = new ArrayList<>();
|
||||
private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
|
||||
private MediaOutputController mMediaOutputController;
|
||||
private int mHeaderIconRes;
|
||||
private IconCompat mIconCompat;
|
||||
private CharSequence mHeaderTitle;
|
||||
private CharSequence mHeaderSubtitle;
|
||||
private String mStopText;
|
||||
private boolean mIsBroadcasting;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
|
||||
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
|
||||
when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
|
||||
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE);
|
||||
mMediaControllers.add(mMediaController);
|
||||
when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
|
||||
|
||||
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
|
||||
mMediaSessionManager, mLocalBluetoothManager, mStarter,
|
||||
mNotificationEntryManager, mDialogLaunchAnimator,
|
||||
@@ -173,6 +198,59 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
|
||||
verify(mMediaOutputBaseAdapter).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_isBroadcasting_verifyRegisterLeBroadcastServiceCallBack() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
mIsBroadcasting = true;
|
||||
|
||||
mMediaOutputBaseDialogImpl.onStart();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcast).registerServiceCallBack(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_notBroadcasting_noRegisterLeBroadcastServiceCallBack() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
mIsBroadcasting = false;
|
||||
|
||||
mMediaOutputBaseDialogImpl.onStart();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcast, never()).registerServiceCallBack(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_isBroadcasting_verifyUnregisterLeBroadcastServiceCallBack() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
mIsBroadcasting = true;
|
||||
|
||||
mMediaOutputBaseDialogImpl.onStop();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcast).unregisterServiceCallBack(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_notBroadcasting_noUnregisterLeBroadcastServiceCallBack() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
mIsBroadcasting = false;
|
||||
|
||||
mMediaOutputBaseDialogImpl.onStop();
|
||||
|
||||
verify(mLocalBluetoothLeBroadcast, never()).unregisterServiceCallBack(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_checkStopText() {
|
||||
mStopText = "test_string";
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final Button stop = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(R.id.stop);
|
||||
|
||||
assertThat(stop.getText().toString()).isEqualTo(mStopText);
|
||||
}
|
||||
|
||||
class MediaOutputBaseDialogImpl extends MediaOutputBaseDialog {
|
||||
|
||||
MediaOutputBaseDialogImpl(Context context, BroadcastSender broadcastSender,
|
||||
@@ -216,5 +294,15 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
|
||||
int getStopButtonVisibility() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBroadcastSupported() {
|
||||
return mIsBroadcasting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getStopButtonText() {
|
||||
return mStopText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@ package com.android.systemui.media.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
@@ -32,7 +35,9 @@ import android.view.View;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.settingslib.media.LocalMediaManager;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
@@ -60,7 +65,13 @@ public class MediaOutputDialogTest extends SysuiTestCase {
|
||||
|
||||
// Mock
|
||||
private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
|
||||
private MediaController mMediaController = mock(MediaController.class);
|
||||
private PlaybackState mPlaybackState = mock(PlaybackState.class);
|
||||
private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
|
||||
private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
|
||||
LocalBluetoothProfileManager.class);
|
||||
private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
|
||||
LocalBluetoothLeBroadcast.class);
|
||||
private final ActivityStarter mStarter = mock(ActivityStarter.class);
|
||||
private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
|
||||
private final LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
|
||||
@@ -72,12 +83,21 @@ public class MediaOutputDialogTest extends SysuiTestCase {
|
||||
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
|
||||
NearbyMediaDevicesManager.class);
|
||||
|
||||
private List<MediaController> mMediaControllers = new ArrayList<>();
|
||||
private MediaOutputDialog mMediaOutputDialog;
|
||||
private MediaOutputController mMediaOutputController;
|
||||
private final List<String> mFeatures = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
|
||||
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
|
||||
when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
|
||||
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE);
|
||||
mMediaControllers.add(mMediaController);
|
||||
when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
|
||||
|
||||
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
|
||||
mMediaSessionManager, mLocalBluetoothManager, mStarter,
|
||||
mNotificationEntryManager, mDialogLaunchAnimator,
|
||||
@@ -116,6 +136,13 @@ public class MediaOutputDialogTest extends SysuiTestCase {
|
||||
mFeatures.add(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK);
|
||||
|
||||
assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
|
||||
|
||||
mFeatures.clear();
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
|
||||
mLocalBluetoothLeBroadcast);
|
||||
when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
|
||||
when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
|
||||
assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user