summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt18
-rw-r--r--media/java/android/media/AudioManager.java28
-rw-r--r--media/java/android/media/MediaMetadata.java4
-rw-r--r--media/java/android/media/session/ISession.aidl3
-rw-r--r--media/java/android/media/session/MediaSession.java11
-rw-r--r--media/java/android/media/session/MediaSessionLegacyHelper.java2
-rw-r--r--media/java/android/media/session/MediaSessionManager.java1
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java13
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java87
9 files changed, 110 insertions, 57 deletions
diff --git a/api/current.txt b/api/current.txt
index 9b211c28201f..f5a4973f578a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14142,10 +14142,10 @@ package android.media {
method public void loadSoundEffects();
method public void playSoundEffect(int);
method public void playSoundEffect(int, float);
- method public void registerMediaButtonEventReceiver(android.content.ComponentName);
- method public void registerMediaButtonEventReceiver(android.app.PendingIntent);
- method public void registerRemoteControlClient(android.media.RemoteControlClient);
- method public boolean registerRemoteController(android.media.RemoteController);
+ method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
+ method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
+ method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
+ method public deprecated boolean registerRemoteController(android.media.RemoteController);
method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
method public deprecated void setBluetoothA2dpOn(boolean);
method public void setBluetoothScoOn(boolean);
@@ -14164,10 +14164,10 @@ package android.media {
method public void startBluetoothSco();
method public void stopBluetoothSco();
method public void unloadSoundEffects();
- method public void unregisterMediaButtonEventReceiver(android.content.ComponentName);
- method public void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
- method public void unregisterRemoteControlClient(android.media.RemoteControlClient);
- method public void unregisterRemoteController(android.media.RemoteController);
+ method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
+ method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
+ method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
+ method public deprecated void unregisterRemoteController(android.media.RemoteController);
field public static final java.lang.String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
field public static final deprecated java.lang.String ACTION_SCO_AUDIO_STATE_CHANGED = "android.media.SCO_AUDIO_STATE_CHANGED";
field public static final java.lang.String ACTION_SCO_AUDIO_STATE_UPDATED = "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
@@ -16643,6 +16643,7 @@ package android.media.session {
method public void setExtras(android.os.Bundle);
method public void setFlags(int);
method public void setLaunchActivity(android.app.PendingIntent);
+ method public void setMediaButtonReceiver(android.app.PendingIntent);
method public void setMediaRouter(android.media.routing.MediaRouter);
method public void setMetadata(android.media.MediaMetadata);
method public void setPlaybackState(android.media.session.PlaybackState);
@@ -16705,6 +16706,7 @@ package android.media.session {
public final class MediaSessionManager {
method public void addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, android.content.ComponentName);
method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
+ method public void removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener);
}
public static abstract class MediaSessionManager.SessionListener {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 20ac8e9ef6fd..111612756c95 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -27,7 +27,10 @@ import android.content.Intent;
import android.media.RemoteController.OnClientUpdateListener;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicyConfig;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -2218,7 +2221,9 @@ public class AudioManager {
* that will receive the media button intent. This broadcast receiver must be declared
* in the application manifest. The package of the component must match that of
* the context you're registering from.
+ * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
*/
+ @Deprecated
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
@@ -2244,9 +2249,12 @@ public class AudioManager {
* you know you will continue running for the full time until unregistering the
* PendingIntent.
* @param eventReceiver target that will receive media button intents. The PendingIntent
- * will be sent as-is when a media button action occurs, with {@link Intent#EXTRA_KEY_EVENT}
- * added and holding the key code of the media button that was pressed.
+ * will be sent an {@link Intent#ACTION_MEDIA_BUTTON} event when a media button action
+ * occurs, with {@link Intent#EXTRA_KEY_EVENT} added and holding the key code of the
+ * media button that was pressed.
+ * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
*/
+ @Deprecated
public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) {
if (eventReceiver == null) {
return;
@@ -2271,7 +2279,9 @@ public class AudioManager {
* Unregister the receiver of MEDIA_BUTTON intents.
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
+ * @deprecated Use {@link MediaSession} instead.
*/
+ @Deprecated
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
@@ -2289,7 +2299,9 @@ public class AudioManager {
* Unregister the receiver of MEDIA_BUTTON intents.
* @param eventReceiver same PendingIntent that was registed with
* {@link #registerMediaButtonEventReceiver(PendingIntent)}.
+ * @deprecated Use {@link MediaSession} instead.
*/
+ @Deprecated
public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) {
if (eventReceiver == null) {
return;
@@ -2311,7 +2323,9 @@ public class AudioManager {
* @param rcClient The remote control client from which remote controls will receive
* information to display.
* @see RemoteControlClient
+ * @deprecated Use {@link MediaSession} instead.
*/
+ @Deprecated
public void registerRemoteControlClient(RemoteControlClient rcClient) {
if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
return;
@@ -2324,7 +2338,9 @@ public class AudioManager {
* remote controls.
* @param rcClient The remote control client to unregister.
* @see #registerRemoteControlClient(RemoteControlClient)
+ * @deprecated Use {@link MediaSession} instead.
*/
+ @Deprecated
public void unregisterRemoteControlClient(RemoteControlClient rcClient) {
if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
return;
@@ -2342,7 +2358,11 @@ public class AudioManager {
* @param rctlr the object to register.
* @return true if the {@link RemoteController} was successfully registered, false if an
* error occurred, due to an internal system error, or insufficient permissions.
+ * @deprecated Use
+ * {@link MediaSessionManager#addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, ComponentName)}
+ * and {@link MediaController} instead.
*/
+ @Deprecated
public boolean registerRemoteController(RemoteController rctlr) {
if (rctlr == null) {
return false;
@@ -2355,7 +2375,11 @@ public class AudioManager {
* Unregisters a {@link RemoteController}, causing it to no longer receive media metadata and
* playback state information, and no longer be capable of controlling playback.
* @param rctlr the object to unregister.
+ * @deprecated Use
+ * {@link MediaSessionManager#removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener)}
+ * instead.
*/
+ @Deprecated
public void unregisterRemoteController(RemoteController rctlr) {
if (rctlr == null) {
return;
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 5d2f3bd58870..3f7ebce89170 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -19,6 +19,7 @@ import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.format.Time;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
@@ -73,7 +74,8 @@ public final class MediaMetadata implements Parcelable {
public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
/**
- * The date the media was created or published as TODO determine format.
+ * The date the media was created or published. The format is unspecified
+ * but RFC 3339 is recommended.
*/
public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 0b8b0d4a139e..af3b72e7f49f 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -16,7 +16,6 @@
package android.media.session;
import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
@@ -37,7 +36,7 @@ interface ISession {
void setFlags(int flags);
void setActive(boolean active);
void setMediaRouter(in IMediaRouter router);
- void setMediaButtonReceiver(in ComponentName mbr);
+ void setMediaButtonReceiver(in PendingIntent mbr);
void setLaunchPendingIntent(in PendingIntent pi);
void destroy();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 5833492cf566..a8786335fa67 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -254,13 +254,14 @@ public final class MediaSession {
}
/**
- * Set a media button event receiver component to use to restart playback
- * after an app has been stopped.
+ * Set a pending intent for your media button receiver to allow restarting
+ * playback after the session has been stopped. If your app is started in
+ * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
+ * the pending intent.
*
- * @param mbr The receiver component to send the media button event to.
- * @hide
+ * @param mbr The {@link PendingIntent} to send the media button event to.
*/
- public void setMediaButtonReceiver(@Nullable ComponentName mbr) {
+ public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
try {
mBinder.setMediaButtonReceiver(mbr);
} catch (RemoteException e) {
diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java
index a6963cfe98af..8ea2039625bc 100644
--- a/media/java/android/media/session/MediaSessionLegacyHelper.java
+++ b/media/java/android/media/session/MediaSessionLegacyHelper.java
@@ -304,7 +304,7 @@ public class MediaSessionLegacyHelper {
holder.mMediaButtonReceiver = new MediaButtonReceiver(pi, context);
holder.mSession.addCallback(holder.mMediaButtonReceiver, mHandler);
- holder.mSession.setMediaButtonReceiver(mbrComponent);
+ holder.mSession.setMediaButtonReceiver(pi);
if (DEBUG) {
Log.d(TAG, "addMediaButtonListener added " + pi);
}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 824b39708d49..ca41965e6ded 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -175,7 +175,6 @@ public final class MediaSessionManager {
* Stop receiving active sessions updates on the specified listener.
*
* @param listener The listener to remove.
- * @hide
*/
public void removeActiveSessionsListener(@NonNull SessionListener listener) {
if (listener == null) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 4ceb21307aaa..d0bcfd408ff9 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -99,7 +99,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private long mFlags;
private IMediaRouter mMediaRouter;
- private ComponentName mMediaButtonReceiver;
+ private PendingIntent mMediaButtonReceiver;
private PendingIntent mLaunchIntent;
// TransportPerformer fields
@@ -170,7 +170,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
return mSessionInfo;
}
- public ComponentName getMediaButtonReceiver() {
+ /**
+ * Get the intent the app set for their media button receiver.
+ *
+ * @return The pending intent set by the app or null.
+ */
+ public PendingIntent getMediaButtonReceiver() {
return mMediaButtonReceiver;
}
@@ -648,8 +653,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
@Override
- public void setMediaButtonReceiver(ComponentName mbr) {
- mMediaButtonReceiver = mbr;
+ public void setMediaButtonReceiver(PendingIntent pi) {
+ mMediaButtonReceiver = pi;
}
@Override
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index b0ccd622715a..ce2899d3f24e 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -20,6 +20,8 @@ import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -407,16 +409,6 @@ public class MediaSessionService extends SystemService implements Monitor {
return user;
}
- private int findIndexOfSessionForIdLocked(String sessionId) {
- for (int i = mAllSessions.size() - 1; i >= 0; i--) {
- MediaSessionRecord session = mAllSessions.get(i);
- if (TextUtils.equals(session.getSessionInfo().getId(), sessionId)) {
- return i;
- }
- }
- return -1;
- }
-
private int findIndexOfSessionsListenerLocked(IActiveSessionsListener listener) {
for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
if (mSessionsListeners.get(i).mListener == listener) {
@@ -436,7 +428,7 @@ public class MediaSessionService extends SystemService implements Monitor {
List<MediaSessionRecord> records = mPriorityStack.getActiveSessions(userId);
int size = records.size();
if (size > 0) {
- persistMediaButtonReceiverLocked(records.get(0));
+ rememberMediaButtonReceiverLocked(records.get(0));
}
ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>();
for (int i = 0; i < size; i++) {
@@ -469,13 +461,11 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
- private void persistMediaButtonReceiverLocked(MediaSessionRecord record) {
- ComponentName receiver = record.getMediaButtonReceiver();
- if (receiver != null) {
- Settings.System.putStringForUser(mContentResolver,
- Settings.System.MEDIA_BUTTON_RECEIVER,
- receiver == null ? "" : receiver.flattenToString(),
- UserHandle.USER_CURRENT);
+ private void rememberMediaButtonReceiverLocked(MediaSessionRecord record) {
+ PendingIntent receiver = record.getMediaButtonReceiver();
+ UserRecord user = mUserRecords.get(record.getUserId());
+ if (receiver != null && user != null) {
+ user.mLastMediaButtonReceiver = receiver;
}
}
@@ -486,6 +476,7 @@ public class MediaSessionService extends SystemService implements Monitor {
final class UserRecord {
private final int mUserId;
private final ArrayList<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();
+ private PendingIntent mLastMediaButtonReceiver;
public UserRecord(Context context, int userId) {
mUserId = userId;
@@ -521,6 +512,7 @@ public class MediaSessionService extends SystemService implements Monitor {
public void dumpLocked(PrintWriter pw, String prefix) {
pw.println(prefix + "Record for user " + mUserId);
String indent = prefix + " ";
+ pw.println(indent + "MediaButtonReceiver:" + mLastMediaButtonReceiver);
int size = mSessions.size();
pw.println(indent + size + " Sessions:");
for (int i = 0; i < size; i++) {
@@ -843,21 +835,43 @@ public class MediaSessionService extends SystemService implements Monitor {
needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
mKeyEventReceiver);
} else {
- if (needWakeLock) {
- mMediaEventWakeLock.acquire();
- }
- if (DEBUG) {
- Log.d(TAG, "Sending media key ordered broadcast");
- }
- // Fallback to legacy behavior
- Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
- keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- if (needWakeLock) {
- keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED,
- WAKELOCK_RELEASE_ON_FINISHED);
+ // Launch the last PendingIntent we had with priority
+ int userId = ActivityManager.getCurrentUser();
+ UserRecord user = mUserRecords.get(userId);
+ if (user.mLastMediaButtonReceiver != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Sending media key to last known PendingIntent");
+ }
+ if (needWakeLock) {
+ mKeyEventReceiver.aquireWakeLockLocked();
+ }
+ Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ try {
+ user.mLastMediaButtonReceiver.send(getContext(),
+ needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
+ mediaButtonIntent, mKeyEventReceiver, null);
+ } catch (CanceledException e) {
+ Log.i(TAG, "Error sending key event to media button receiver "
+ + user.mLastMediaButtonReceiver, e);
+ }
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Sending media key ordered broadcast");
+ }
+ if (needWakeLock) {
+ mMediaEventWakeLock.acquire();
+ }
+ // Fallback to legacy behavior
+ Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+ keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ if (needWakeLock) {
+ keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED,
+ WAKELOCK_RELEASE_ON_FINISHED);
+ }
+ getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
+ null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null);
}
- getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
- null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null);
}
}
@@ -904,7 +918,8 @@ public class MediaSessionService extends SystemService implements Monitor {
private KeyEventWakeLockReceiver mKeyEventReceiver = new KeyEventWakeLockReceiver(mHandler);
- class KeyEventWakeLockReceiver extends ResultReceiver implements Runnable {
+ class KeyEventWakeLockReceiver extends ResultReceiver implements Runnable,
+ PendingIntent.OnFinished {
private final Handler mHandler;
private int mRefCount = 0;
private int mLastTimeoutId = 0;
@@ -963,6 +978,12 @@ public class MediaSessionService extends SystemService implements Monitor {
mMediaEventWakeLock.release();
mHandler.removeCallbacks(this);
}
+
+ @Override
+ public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+ String resultData, Bundle resultExtras) {
+ onReceiveResult(resultCode, null);
+ }
};
BroadcastReceiver mKeyEventDone = new BroadcastReceiver() {