Merge "Get media devices for each media application" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a86df87eaa
@@ -44,9 +44,11 @@ import android.widget.ImageView;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
||||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||||
|
|
||||||
|
import com.android.settingslib.media.LocalMediaManager;
|
||||||
import com.android.settingslib.media.MediaDevice;
|
import com.android.settingslib.media.MediaDevice;
|
||||||
import com.android.settingslib.media.MediaOutputSliceConstants;
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
import com.android.settingslib.widget.AdaptiveIcon;
|
import com.android.settingslib.widget.AdaptiveIcon;
|
||||||
@@ -66,6 +68,7 @@ import java.util.concurrent.Executor;
|
|||||||
public class MediaControlPanel {
|
public class MediaControlPanel {
|
||||||
private static final String TAG = "MediaControlPanel";
|
private static final String TAG = "MediaControlPanel";
|
||||||
private final NotificationMediaManager mMediaManager;
|
private final NotificationMediaManager mMediaManager;
|
||||||
|
@Nullable private final LocalMediaManager mLocalMediaManager;
|
||||||
private final Executor mForegroundExecutor;
|
private final Executor mForegroundExecutor;
|
||||||
private final Executor mBackgroundExecutor;
|
private final Executor mBackgroundExecutor;
|
||||||
|
|
||||||
@@ -77,6 +80,7 @@ public class MediaControlPanel {
|
|||||||
private int mForegroundColor;
|
private int mForegroundColor;
|
||||||
private int mBackgroundColor;
|
private int mBackgroundColor;
|
||||||
protected ComponentName mRecvComponent;
|
protected ComponentName mRecvComponent;
|
||||||
|
private MediaDevice mDevice;
|
||||||
private boolean mIsRegistered = false;
|
private boolean mIsRegistered = false;
|
||||||
|
|
||||||
private final int[] mActionIds;
|
private final int[] mActionIds;
|
||||||
@@ -121,19 +125,44 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final LocalMediaManager.DeviceCallback mDeviceCallback =
|
||||||
|
new LocalMediaManager.DeviceCallback() {
|
||||||
|
@Override
|
||||||
|
public void onDeviceListUpdate(List<MediaDevice> devices) {
|
||||||
|
if (mLocalMediaManager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MediaDevice currentDevice = mLocalMediaManager.getCurrentConnectedDevice();
|
||||||
|
// Check because this can be called several times while changing devices
|
||||||
|
if (mDevice == null || !mDevice.equals(currentDevice)) {
|
||||||
|
mDevice = currentDevice;
|
||||||
|
updateDevice(mDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
|
||||||
|
if (mDevice == null || !mDevice.equals(device)) {
|
||||||
|
mDevice = device;
|
||||||
|
updateDevice(mDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a new control panel
|
* Initialize a new control panel
|
||||||
* @param context
|
* @param context
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param manager
|
* @param manager
|
||||||
|
* @param routeManager Manager used to listen for device change events.
|
||||||
* @param layoutId layout resource to use for this control panel
|
* @param layoutId layout resource to use for this control panel
|
||||||
* @param actionIds resource IDs for action buttons in the layout
|
* @param actionIds resource IDs for action buttons in the layout
|
||||||
* @param foregroundExecutor foreground executor
|
* @param foregroundExecutor foreground executor
|
||||||
* @param backgroundExecutor background executor, used for processing artwork
|
* @param backgroundExecutor background executor, used for processing artwork
|
||||||
*/
|
*/
|
||||||
public MediaControlPanel(Context context, ViewGroup parent, NotificationMediaManager manager,
|
public MediaControlPanel(Context context, ViewGroup parent, NotificationMediaManager manager,
|
||||||
@LayoutRes int layoutId, int[] actionIds, Executor foregroundExecutor,
|
@Nullable LocalMediaManager routeManager, @LayoutRes int layoutId, int[] actionIds,
|
||||||
Executor backgroundExecutor) {
|
Executor foregroundExecutor, Executor backgroundExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
mMediaNotifView = (LinearLayout) inflater.inflate(layoutId, parent, false);
|
mMediaNotifView = (LinearLayout) inflater.inflate(layoutId, parent, false);
|
||||||
@@ -144,6 +173,7 @@ public class MediaControlPanel {
|
|||||||
// mStateListener to be unregistered in detach.
|
// mStateListener to be unregistered in detach.
|
||||||
mMediaNotifView.addOnAttachStateChangeListener(mStateListener);
|
mMediaNotifView.addOnAttachStateChangeListener(mStateListener);
|
||||||
mMediaManager = manager;
|
mMediaManager = manager;
|
||||||
|
mLocalMediaManager = routeManager;
|
||||||
mActionIds = actionIds;
|
mActionIds = actionIds;
|
||||||
mForegroundExecutor = foregroundExecutor;
|
mForegroundExecutor = foregroundExecutor;
|
||||||
mBackgroundExecutor = backgroundExecutor;
|
mBackgroundExecutor = backgroundExecutor;
|
||||||
@@ -176,7 +206,7 @@ public class MediaControlPanel {
|
|||||||
* @param device
|
* @param device
|
||||||
*/
|
*/
|
||||||
public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor,
|
public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor,
|
||||||
int bgColor, PendingIntent contentIntent, String appNameString, MediaDevice device) {
|
int bgColor, PendingIntent contentIntent, String appNameString) {
|
||||||
mToken = token;
|
mToken = token;
|
||||||
mForegroundColor = iconColor;
|
mForegroundColor = iconColor;
|
||||||
mBackgroundColor = bgColor;
|
mBackgroundColor = bgColor;
|
||||||
@@ -253,9 +283,9 @@ public class MediaControlPanel {
|
|||||||
|
|
||||||
// Transfer chip
|
// Transfer chip
|
||||||
mSeamless = mMediaNotifView.findViewById(R.id.media_seamless);
|
mSeamless = mMediaNotifView.findViewById(R.id.media_seamless);
|
||||||
if (mSeamless != null) {
|
if (mSeamless != null && mLocalMediaManager != null) {
|
||||||
mSeamless.setVisibility(View.VISIBLE);
|
mSeamless.setVisibility(View.VISIBLE);
|
||||||
updateDevice(device);
|
updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
|
||||||
ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
|
ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
|
||||||
mSeamless.setOnClickListener(v -> {
|
mSeamless.setOnClickListener(v -> {
|
||||||
final Intent intent = new Intent()
|
final Intent intent = new Intent()
|
||||||
@@ -366,7 +396,7 @@ public class MediaControlPanel {
|
|||||||
* Update the current device information
|
* Update the current device information
|
||||||
* @param device device information to display
|
* @param device device information to display
|
||||||
*/
|
*/
|
||||||
public void updateDevice(MediaDevice device) {
|
private void updateDevice(MediaDevice device) {
|
||||||
if (mSeamless == null) {
|
if (mSeamless == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -456,6 +486,10 @@ public class MediaControlPanel {
|
|||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
if (!mIsRegistered) {
|
if (!mIsRegistered) {
|
||||||
mMediaManager.addCallback(mMediaListener);
|
mMediaManager.addCallback(mMediaListener);
|
||||||
|
if (mLocalMediaManager != null) {
|
||||||
|
mLocalMediaManager.registerCallback(mDeviceCallback);
|
||||||
|
mLocalMediaManager.startScan();
|
||||||
|
}
|
||||||
mIsRegistered = true;
|
mIsRegistered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,6 +497,10 @@ public class MediaControlPanel {
|
|||||||
private void makeInactive() {
|
private void makeInactive() {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
if (mIsRegistered) {
|
if (mIsRegistered) {
|
||||||
|
if (mLocalMediaManager != null) {
|
||||||
|
mLocalMediaManager.stopScan();
|
||||||
|
mLocalMediaManager.unregisterCallback(mDeviceCallback);
|
||||||
|
}
|
||||||
mMediaManager.removeCallback(mMediaListener);
|
mMediaManager.removeCallback(mMediaListener);
|
||||||
mIsRegistered = false;
|
mIsRegistered = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.settingslib.media.MediaDevice;
|
import com.android.settingslib.media.LocalMediaManager;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.media.MediaControlPanel;
|
import com.android.systemui.media.MediaControlPanel;
|
||||||
import com.android.systemui.media.SeekBarObserver;
|
import com.android.systemui.media.SeekBarObserver;
|
||||||
@@ -74,9 +74,10 @@ public class QSMediaPlayer extends MediaControlPanel {
|
|||||||
* @param backgroundExecutor
|
* @param backgroundExecutor
|
||||||
*/
|
*/
|
||||||
public QSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
|
public QSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
|
||||||
Executor foregroundExecutor, DelayableExecutor backgroundExecutor) {
|
LocalMediaManager routeManager, Executor foregroundExecutor,
|
||||||
super(context, parent, manager, R.layout.qs_media_panel, QS_ACTION_IDS, foregroundExecutor,
|
DelayableExecutor backgroundExecutor) {
|
||||||
backgroundExecutor);
|
super(context, parent, manager, routeManager, R.layout.qs_media_panel, QS_ACTION_IDS,
|
||||||
|
foregroundExecutor, backgroundExecutor);
|
||||||
mParent = (QSPanel) parent;
|
mParent = (QSPanel) parent;
|
||||||
mBackgroundExecutor = backgroundExecutor;
|
mBackgroundExecutor = backgroundExecutor;
|
||||||
mSeekBarViewModel = new SeekBarViewModel(backgroundExecutor);
|
mSeekBarViewModel = new SeekBarViewModel(backgroundExecutor);
|
||||||
@@ -101,12 +102,12 @@ public class QSMediaPlayer extends MediaControlPanel {
|
|||||||
* @param device current playback device
|
* @param device current playback device
|
||||||
*/
|
*/
|
||||||
public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor,
|
public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor,
|
||||||
int bgColor, View actionsContainer, Notification notif, MediaDevice device) {
|
int bgColor, View actionsContainer, Notification notif) {
|
||||||
|
|
||||||
String appName = Notification.Builder.recoverBuilder(getContext(), notif)
|
String appName = Notification.Builder.recoverBuilder(getContext(), notif)
|
||||||
.loadHeaderAppName();
|
.loadHeaderAppName();
|
||||||
super.setMediaSession(token, icon, iconColor, bgColor, notif.contentIntent,
|
super.setMediaSession(token, icon, iconColor, bgColor, notif.contentIntent,
|
||||||
appName, device);
|
appName);
|
||||||
|
|
||||||
// Media controls
|
// Media controls
|
||||||
LinearLayout parentActionsLayout = (LinearLayout) actionsContainer;
|
LinearLayout parentActionsLayout = (LinearLayout) actionsContainer;
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ import com.android.settingslib.Utils;
|
|||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.settingslib.media.InfoMediaManager;
|
import com.android.settingslib.media.InfoMediaManager;
|
||||||
import com.android.settingslib.media.LocalMediaManager;
|
import com.android.settingslib.media.LocalMediaManager;
|
||||||
import com.android.settingslib.media.MediaDevice;
|
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -75,7 +74,6 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -105,8 +103,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
private final LocalBluetoothManager mLocalBluetoothManager;
|
private final LocalBluetoothManager mLocalBluetoothManager;
|
||||||
private final Executor mForegroundExecutor;
|
private final Executor mForegroundExecutor;
|
||||||
private final DelayableExecutor mBackgroundExecutor;
|
private final DelayableExecutor mBackgroundExecutor;
|
||||||
private LocalMediaManager mLocalMediaManager;
|
|
||||||
private MediaDevice mDevice;
|
|
||||||
private boolean mUpdateCarousel = false;
|
private boolean mUpdateCarousel = false;
|
||||||
|
|
||||||
protected boolean mExpanded;
|
protected boolean mExpanded;
|
||||||
@@ -130,34 +126,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
private BrightnessMirrorController mBrightnessMirrorController;
|
private BrightnessMirrorController mBrightnessMirrorController;
|
||||||
private View mDivider;
|
private View mDivider;
|
||||||
|
|
||||||
private final LocalMediaManager.DeviceCallback mDeviceCallback =
|
|
||||||
new LocalMediaManager.DeviceCallback() {
|
|
||||||
@Override
|
|
||||||
public void onDeviceListUpdate(List<MediaDevice> devices) {
|
|
||||||
if (mLocalMediaManager == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MediaDevice currentDevice = mLocalMediaManager.getCurrentConnectedDevice();
|
|
||||||
// Check because this can be called several times while changing devices
|
|
||||||
if (mDevice == null || !mDevice.equals(currentDevice)) {
|
|
||||||
mDevice = currentDevice;
|
|
||||||
for (QSMediaPlayer p : mMediaPlayers) {
|
|
||||||
p.updateDevice(mDevice);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
|
|
||||||
if (mDevice == null || !mDevice.equals(device)) {
|
|
||||||
mDevice = device;
|
|
||||||
for (QSMediaPlayer p : mMediaPlayers) {
|
|
||||||
p.updateDevice(mDevice);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public QSPanel(
|
public QSPanel(
|
||||||
@Named(VIEW_CONTEXT) Context context,
|
@Named(VIEW_CONTEXT) Context context,
|
||||||
@@ -277,7 +245,14 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
Log.d(TAG, "creating new player");
|
Log.d(TAG, "creating new player");
|
||||||
player = new QSMediaPlayer(mContext, this, mNotificationMediaManager,
|
// Set up listener for device changes
|
||||||
|
// TODO: integrate with MediaTransferManager?
|
||||||
|
InfoMediaManager imm = new InfoMediaManager(mContext, notif.getPackageName(),
|
||||||
|
notif.getNotification(), mLocalBluetoothManager);
|
||||||
|
LocalMediaManager routeManager = new LocalMediaManager(mContext, mLocalBluetoothManager,
|
||||||
|
imm, notif.getPackageName());
|
||||||
|
|
||||||
|
player = new QSMediaPlayer(mContext, this, mNotificationMediaManager, routeManager,
|
||||||
mForegroundExecutor, mBackgroundExecutor);
|
mForegroundExecutor, mBackgroundExecutor);
|
||||||
player.setListening(mListening);
|
player.setListening(mListening);
|
||||||
if (player.isPlaying()) {
|
if (player.isPlaying()) {
|
||||||
@@ -292,22 +267,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
|
|
||||||
Log.d(TAG, "setting player session");
|
Log.d(TAG, "setting player session");
|
||||||
player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer,
|
player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer,
|
||||||
notif.getNotification(), mDevice);
|
notif.getNotification());
|
||||||
|
|
||||||
if (mMediaPlayers.size() > 0) {
|
if (mMediaPlayers.size() > 0) {
|
||||||
((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE);
|
((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if (mLocalMediaManager == null) {
|
|
||||||
// Set up listener for device changes
|
|
||||||
// TODO: integrate with MediaTransferManager?
|
|
||||||
InfoMediaManager imm =
|
|
||||||
new InfoMediaManager(mContext, null, null, mLocalBluetoothManager);
|
|
||||||
mLocalMediaManager = new LocalMediaManager(mContext, mLocalBluetoothManager, imm,
|
|
||||||
null);
|
|
||||||
mLocalMediaManager.startScan();
|
|
||||||
mDevice = mLocalMediaManager.getCurrentConnectedDevice();
|
|
||||||
mLocalMediaManager.registerCallback(mDeviceCallback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,11 +293,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
mMediaCarousel.removeView(player.getView());
|
mMediaCarousel.removeView(player.getView());
|
||||||
if (mMediaPlayers.size() == 0) {
|
if (mMediaPlayers.size() == 0) {
|
||||||
((View) mMediaCarousel.getParent()).setVisibility(View.GONE);
|
((View) mMediaCarousel.getParent()).setVisibility(View.GONE);
|
||||||
if (mLocalMediaManager != null) {
|
|
||||||
mLocalMediaManager.stopScan();
|
|
||||||
mLocalMediaManager.unregisterCallback(mDeviceCallback);
|
|
||||||
mLocalMediaManager = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -404,11 +362,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
|||||||
mBrightnessMirrorController.removeCallback(this);
|
mBrightnessMirrorController.removeCallback(this);
|
||||||
}
|
}
|
||||||
mDumpManager.unregisterDumpable(getDumpableTag());
|
mDumpManager.unregisterDumpable(getDumpableTag());
|
||||||
if (mLocalMediaManager != null) {
|
|
||||||
mLocalMediaManager.stopScan();
|
|
||||||
mLocalMediaManager.unregisterCallback(mDeviceCallback);
|
|
||||||
mLocalMediaManager = null;
|
|
||||||
}
|
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class QuickQSMediaPlayer extends MediaControlPanel {
|
|||||||
*/
|
*/
|
||||||
public QuickQSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
|
public QuickQSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
|
||||||
Executor foregroundExecutor, Executor backgroundExecutor) {
|
Executor foregroundExecutor, Executor backgroundExecutor) {
|
||||||
super(context, parent, manager, R.layout.qqs_media_panel, QQS_ACTION_IDS,
|
super(context, parent, manager, null, R.layout.qqs_media_panel, QQS_ACTION_IDS,
|
||||||
foregroundExecutor, backgroundExecutor);
|
foregroundExecutor, backgroundExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ public class QuickQSMediaPlayer extends MediaControlPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setMediaSession(token, icon, iconColor, bgColor, contentIntent, null, null);
|
super.setMediaSession(token, icon, iconColor, bgColor, contentIntent, null);
|
||||||
|
|
||||||
LinearLayout parentActionsLayout = (LinearLayout) actionsContainer;
|
LinearLayout parentActionsLayout = (LinearLayout) actionsContainer;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user