Merge "Clean up mediabrowser callbacks" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
61ff257f02
@@ -98,6 +98,7 @@ public class MediaControlPanel {
|
||||
private SharedPreferences mSharedPrefs;
|
||||
private boolean mCheckedForResumption = false;
|
||||
private boolean mIsRemotePlayback;
|
||||
private QSMediaBrowser mQSMediaBrowser;
|
||||
|
||||
// Button IDs used in notifications
|
||||
protected static final int[] NOTIF_ACTION_IDS = {
|
||||
@@ -232,6 +233,11 @@ public class MediaControlPanel {
|
||||
String key) {
|
||||
// Ensure that component names are updated if token has changed
|
||||
if (mToken == null || !mToken.equals(token)) {
|
||||
if (mQSMediaBrowser != null) {
|
||||
Log.d(TAG, "Disconnecting old media browser");
|
||||
mQSMediaBrowser.disconnect();
|
||||
mQSMediaBrowser = null;
|
||||
}
|
||||
mToken = token;
|
||||
mServiceComponent = null;
|
||||
mCheckedForResumption = false;
|
||||
@@ -618,8 +624,22 @@ public class MediaControlPanel {
|
||||
ImageButton btn = mMediaNotifView.findViewById(mActionIds[0]);
|
||||
btn.setOnClickListener(v -> {
|
||||
Log.d(TAG, "Attempting to restart session");
|
||||
QSMediaBrowser browser = new QSMediaBrowser(mContext, null, mServiceComponent);
|
||||
browser.restart();
|
||||
if (mQSMediaBrowser != null) {
|
||||
mQSMediaBrowser.disconnect();
|
||||
}
|
||||
mQSMediaBrowser = new QSMediaBrowser(mContext, new QSMediaBrowser.Callback(){
|
||||
@Override
|
||||
public void onConnected() {
|
||||
Log.d(TAG, "Successfully restarted");
|
||||
}
|
||||
@Override
|
||||
public void onError() {
|
||||
Log.e(TAG, "Error restarting");
|
||||
mQSMediaBrowser.disconnect();
|
||||
mQSMediaBrowser = null;
|
||||
}
|
||||
}, mServiceComponent);
|
||||
mQSMediaBrowser.restart();
|
||||
});
|
||||
btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_play));
|
||||
btn.setImageTintList(ColorStateList.valueOf(mForegroundColor));
|
||||
@@ -654,13 +674,18 @@ public class MediaControlPanel {
|
||||
*/
|
||||
private void tryUpdateResumptionList(ComponentName componentName) {
|
||||
Log.d(TAG, "Testing if we can connect to " + componentName);
|
||||
QSMediaBrowser.testConnection(mContext,
|
||||
if (mQSMediaBrowser != null) {
|
||||
mQSMediaBrowser.disconnect();
|
||||
}
|
||||
mQSMediaBrowser = new QSMediaBrowser(mContext,
|
||||
new QSMediaBrowser.Callback() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
Log.d(TAG, "yes we can resume with " + componentName);
|
||||
mServiceComponent = componentName;
|
||||
updateResumptionList(componentName);
|
||||
mQSMediaBrowser.disconnect();
|
||||
mQSMediaBrowser = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -671,9 +696,12 @@ public class MediaControlPanel {
|
||||
// If it's not active and we can't resume, remove
|
||||
removePlayer();
|
||||
}
|
||||
mQSMediaBrowser.disconnect();
|
||||
mQSMediaBrowser = null;
|
||||
}
|
||||
},
|
||||
componentName);
|
||||
mQSMediaBrowser.testConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,21 +58,25 @@ public class QSMediaBrowser {
|
||||
mContext = context;
|
||||
mCallback = callback;
|
||||
mComponentName = componentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the MediaBrowserService and looks for valid media. If a media item is returned
|
||||
* by the service, QSMediaBrowser.Callback#addTrack will be called with its MediaDescription.
|
||||
* QSMediaBrowser.Callback#onConnected and QSMediaBrowser.Callback#onError will also be called
|
||||
* when the initial connection is successful, or an error occurs. Note that it is possible for
|
||||
* the service to connect but for no playable tracks to be found later.
|
||||
* QSMediaBrowser#disconnect will be called automatically with this function.
|
||||
*/
|
||||
public void findRecentMedia() {
|
||||
Log.d(TAG, "Connecting to " + mComponentName);
|
||||
disconnect();
|
||||
Bundle rootHints = new Bundle();
|
||||
rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
|
||||
mMediaBrowser = new MediaBrowser(mContext,
|
||||
mComponentName,
|
||||
mConnectionCallback,
|
||||
rootHints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the MediaBrowserService and looks for valid media. If a media item is returned
|
||||
* by the service, QSMediaBrowser.Callback#addTrack will be called with its MediaDescription
|
||||
*/
|
||||
public void findRecentMedia() {
|
||||
Log.d(TAG, "Connecting to " + mComponentName);
|
||||
mMediaBrowser.connect();
|
||||
}
|
||||
|
||||
@@ -94,20 +98,22 @@ public class QSMediaBrowser {
|
||||
} else {
|
||||
Log.e(TAG, "Child found but not playable for " + mComponentName);
|
||||
}
|
||||
mMediaBrowser.disconnect();
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String parentId) {
|
||||
Log.e(TAG, "Subscribe error for " + mComponentName + ": " + parentId);
|
||||
mMediaBrowser.disconnect();
|
||||
mCallback.onError();
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String parentId, Bundle options) {
|
||||
Log.e(TAG, "Subscribe error for " + mComponentName + ": " + parentId
|
||||
+ ", options: " + options);
|
||||
mMediaBrowser.disconnect();
|
||||
mCallback.onError();
|
||||
disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,6 +140,8 @@ public class QSMediaBrowser {
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
Log.d(TAG, "Connection suspended for " + mComponentName);
|
||||
mCallback.onError();
|
||||
disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,16 +151,28 @@ public class QSMediaBrowser {
|
||||
public void onConnectionFailed() {
|
||||
Log.e(TAG, "Connection failed for " + mComponentName);
|
||||
mCallback.onError();
|
||||
disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to the MediaBrowserService and starts playback
|
||||
* Disconnect the media browser. This should be called after restart or testConnection have
|
||||
* completed to close the connection.
|
||||
*/
|
||||
public void restart() {
|
||||
if (mMediaBrowser.isConnected()) {
|
||||
public void disconnect() {
|
||||
if (mMediaBrowser != null) {
|
||||
mMediaBrowser.disconnect();
|
||||
}
|
||||
mMediaBrowser = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the MediaBrowserService and starts playback. QSMediaBrowser.Callback#onError or
|
||||
* QSMediaBrowser.Callback#onConnected will be called depending on whether it was successful.
|
||||
* QSMediaBrowser#disconnect should be called after this to ensure the connection is closed.
|
||||
*/
|
||||
public void restart() {
|
||||
disconnect();
|
||||
Bundle rootHints = new Bundle();
|
||||
rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
|
||||
mMediaBrowser = new MediaBrowser(mContext, mComponentName,
|
||||
@@ -165,6 +185,17 @@ public class QSMediaBrowser {
|
||||
controller.getTransportControls();
|
||||
controller.getTransportControls().prepare();
|
||||
controller.getTransportControls().play();
|
||||
mCallback.onConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed() {
|
||||
mCallback.onError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
mCallback.onError();
|
||||
}
|
||||
}, rootHints);
|
||||
mMediaBrowser.connect();
|
||||
@@ -192,42 +223,44 @@ public class QSMediaBrowser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test if SystemUI is allowed to connect to the given component as a MediaBrowser
|
||||
* @param mContext the context
|
||||
* @param callback methods onConnected or onError will be called to indicate whether the
|
||||
* connection was successful or not
|
||||
* @param mComponentName Component name of the MediaBrowserService this browser will connect to
|
||||
* Used to test if SystemUI is allowed to connect to the given component as a MediaBrowser.
|
||||
* QSMediaBrowser.Callback#onError or QSMediaBrowser.Callback#onConnected will be called
|
||||
* depending on whether it was successful.
|
||||
* QSMediaBrowser#disconnect should be called after this to ensure the connection is closed.
|
||||
*/
|
||||
public static MediaBrowser testConnection(Context mContext, Callback callback,
|
||||
ComponentName mComponentName) {
|
||||
final MediaBrowser.ConnectionCallback mConnectionCallback =
|
||||
public void testConnection() {
|
||||
disconnect();
|
||||
final MediaBrowser.ConnectionCallback connectionCallback =
|
||||
new MediaBrowser.ConnectionCallback() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
Log.d(TAG, "connected");
|
||||
callback.onConnected();
|
||||
if (mMediaBrowser.getRoot() == null) {
|
||||
mCallback.onError();
|
||||
} else {
|
||||
mCallback.onConnected();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
Log.d(TAG, "suspended");
|
||||
callback.onError();
|
||||
mCallback.onError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed() {
|
||||
Log.d(TAG, "failed");
|
||||
callback.onError();
|
||||
mCallback.onError();
|
||||
}
|
||||
};
|
||||
Bundle rootHints = new Bundle();
|
||||
rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
|
||||
MediaBrowser browser = new MediaBrowser(mContext,
|
||||
mMediaBrowser = new MediaBrowser(mContext,
|
||||
mComponentName,
|
||||
mConnectionCallback,
|
||||
connectionCallback,
|
||||
rootHints);
|
||||
browser.connect();
|
||||
return browser;
|
||||
mMediaBrowser.connect();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -270,27 +270,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
return;
|
||||
}
|
||||
|
||||
QSMediaPlayer player = null;
|
||||
String packageName = notif.getPackageName();
|
||||
for (QSMediaPlayer p : mMediaPlayers) {
|
||||
if (p.getKey() == null) {
|
||||
// No notification key = loaded via mediabrowser, so just match on package
|
||||
if (packageName.equals(p.getMediaPlayerPackage())) {
|
||||
Log.d(TAG, "Found matching resume player by package: " + packageName);
|
||||
player = p;
|
||||
break;
|
||||
}
|
||||
} else if (p.getMediaSessionToken().equals(token)) {
|
||||
Log.d(TAG, "Found matching player by token " + packageName);
|
||||
player = p;
|
||||
break;
|
||||
} else if (packageName.equals(p.getMediaPlayerPackage()) && key.equals(p.getKey())) {
|
||||
// Also match if it's the same package and notification key
|
||||
Log.d(TAG, "Found matching player by package " + packageName + ", " + key);
|
||||
player = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QSMediaPlayer player = findMediaPlayer(packageName, token, key);
|
||||
|
||||
int playerWidth = (int) getResources().getDimension(R.dimen.qs_media_width);
|
||||
int padding = (int) getResources().getDimension(R.dimen.qs_media_padding);
|
||||
@@ -299,7 +280,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
lp.setMarginEnd(padding);
|
||||
|
||||
if (player == null) {
|
||||
Log.d(TAG, "creating new player");
|
||||
Log.d(TAG, "creating new player for " + packageName);
|
||||
// Set up listener for device changes
|
||||
// TODO: integrate with MediaTransferManager?
|
||||
InfoMediaManager imm = new InfoMediaManager(mContext, notif.getPackageName(),
|
||||
@@ -331,6 +312,35 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for an existing media player using the given information
|
||||
* @param packageName
|
||||
* @param token
|
||||
* @param key
|
||||
* @return a player, or null if no match found
|
||||
*/
|
||||
private QSMediaPlayer findMediaPlayer(String packageName, MediaSession.Token token,
|
||||
String key) {
|
||||
for (QSMediaPlayer player : mMediaPlayers) {
|
||||
if (player.getKey() == null || key == null) {
|
||||
// No notification key = loaded via mediabrowser, so just match on package
|
||||
if (packageName.equals(player.getMediaPlayerPackage())) {
|
||||
Log.d(TAG, "Found matching resume player by package: " + packageName);
|
||||
return player;
|
||||
}
|
||||
} else if (player.getMediaSessionToken().equals(token)) {
|
||||
Log.d(TAG, "Found matching player by token " + packageName);
|
||||
return player;
|
||||
} else if (packageName.equals(player.getMediaPlayerPackage())
|
||||
&& key.equals(player.getKey())) {
|
||||
// Also match if it's the same package and notification key
|
||||
Log.d(TAG, "Found matching player by package " + packageName + ", " + key);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected View getMediaPanel() {
|
||||
return mMediaCarousel;
|
||||
}
|
||||
@@ -369,26 +379,30 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
}
|
||||
|
||||
Log.d(TAG, "adding track from browser: " + desc + ", " + component);
|
||||
QSMediaPlayer player = new QSMediaPlayer(mContext, QSPanel.this,
|
||||
null, mForegroundExecutor, mBackgroundExecutor, mActivityStarter);
|
||||
|
||||
// Check if there's an old player for this app
|
||||
String pkgName = component.getPackageName();
|
||||
MediaSession.Token token = browser.getToken();
|
||||
QSMediaPlayer player = findMediaPlayer(pkgName, token, null);
|
||||
|
||||
// Add controls to carousel
|
||||
int playerWidth = (int) getResources().getDimension(R.dimen.qs_media_width);
|
||||
int padding = (int) getResources().getDimension(R.dimen.qs_media_padding);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(playerWidth,
|
||||
LayoutParams.MATCH_PARENT);
|
||||
lp.setMarginStart(padding);
|
||||
lp.setMarginEnd(padding);
|
||||
mMediaCarousel.addView(player.getView(), lp);
|
||||
((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE);
|
||||
mMediaPlayers.add(player);
|
||||
if (player == null) {
|
||||
player = new QSMediaPlayer(mContext, QSPanel.this,
|
||||
null, mForegroundExecutor, mBackgroundExecutor, mActivityStarter);
|
||||
|
||||
// Add to carousel
|
||||
int playerWidth = (int) getResources().getDimension(R.dimen.qs_media_width);
|
||||
int padding = (int) getResources().getDimension(R.dimen.qs_media_padding);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(playerWidth,
|
||||
LayoutParams.MATCH_PARENT);
|
||||
lp.setMarginStart(padding);
|
||||
lp.setMarginEnd(padding);
|
||||
mMediaCarousel.addView(player.getView(), lp);
|
||||
((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE);
|
||||
mMediaPlayers.add(player);
|
||||
}
|
||||
|
||||
int iconColor = Color.DKGRAY;
|
||||
int bgColor = Color.LTGRAY;
|
||||
|
||||
MediaSession.Token token = browser.getToken();
|
||||
player.setMediaSession(token, desc, iconColor, bgColor, browser.getAppIntent(),
|
||||
pkgName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user