diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java index 3894e75630d0b..c1bc4feeb31d6 100644 --- a/media/java/android/media/MediaController2.java +++ b/media/java/android/media/MediaController2.java @@ -123,6 +123,29 @@ public class MediaController2 implements AutoCloseable { } } + /** + * Sends a session command to the session + *
+ * @param command the session command
+ * @param args optional argument
+ */
+ // TODO: make cancelable and provide a way to get the result.
+ public void sendSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
+ synchronized (mLock) {
+ if (mSessionBinder != null) {
+ try {
+ mSessionBinder.sendSessionCommand(mControllerStub, mNextSeqNumber++,
+ command, args);
+ } catch (RuntimeException e) {
+ // No-op
+ }
+ }
+ }
+ }
+
// Called by Controller2Link.onConnected
void onConnected(int seq, Bundle connectionResult) {
final long token = Binder.clearCallingIdentity();
@@ -169,7 +192,14 @@ public class MediaController2 implements AutoCloseable {
// Called by Controller2Link.onSessionCommand
void onSessionCommand(int seq, Session2Command command, Bundle args) {
- // TODO: Implement this
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mCallbackExecutor.execute(() -> {
+ mCallback.onSessionCommand(MediaController2.this, command, args);
+ });
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
private int getNextSeqNumber() {
diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java
index 52e607d07f85c..ad6aa0520ced9 100644
--- a/media/java/android/media/MediaSession2.java
+++ b/media/java/android/media/MediaSession2.java
@@ -81,6 +81,10 @@ public class MediaSession2 implements AutoCloseable {
private final Session2Token mSessionToken;
private final MediaSessionManager mSessionManager;
+ //@GuardedBy("mLock")
+ @SuppressWarnings("WeakerAccess") /* synthetic access */
+ private boolean mClosed;
+
MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity,
@NonNull Executor callbackExecutor, @NonNull SessionCallback callback) {
synchronized (MediaSession2.class) {
@@ -111,6 +115,7 @@ public class MediaSession2 implements AutoCloseable {
Collection
+ * @param command the session command
+ * @param args optional argument
+ */
+ public void broadcastSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
+ Collection
+ * @param controller the controller to get the session command
+ * @param command the session command
+ * @param args optional argument
+ */
+ // TODO: make cancelable and provide a way to get the result.
+ public void sendSessionCommand(@NonNull ControllerInfo controller,
+ @NonNull Session2Command command, @Nullable Bundle args) {
+ if (controller == null) {
+ throw new IllegalArgumentException("controller shouldn't be null");
+ }
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
+ controller.sendSessionCommand(command, args);
+ }
+
boolean isClosed() {
- // TODO: Implement this
- return true;
+ synchronized (mLock) {
+ return mClosed;
+ }
}
// Called by Session2Link.onConnect
@@ -209,12 +253,10 @@ public class MediaSession2 implements AutoCloseable {
final long token = Binder.clearCallingIdentity();
try {
- synchronized (mLock) {
- mCallbackExecutor.execute(() -> {
- mCallback.onDisconnected(MediaSession2.this, controllerInfo);
- });
- mConnectedControllers.remove(controller);
- }
+ mCallbackExecutor.execute(() -> {
+ mCallback.onDisconnected(MediaSession2.this, controllerInfo);
+ });
+ mConnectedControllers.remove(controller);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -223,7 +265,31 @@ public class MediaSession2 implements AutoCloseable {
// Called by Session2Link.onSessionCommand
void onSessionCommand(final Controller2Link controller, final int seq,
final Session2Command command, final Bundle args) {
- // TODO: Implement this
+ if (controller == null) {
+ return;
+ }
+ final ControllerInfo controllerInfo;
+ synchronized (mLock) {
+ controllerInfo = mConnectedControllers.get(controller);
+ }
+ if (controllerInfo == null) {
+ return;
+ }
+
+ // TODO: check allowed commands.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mCallbackExecutor.execute(() -> {
+ try {
+ mCallback.onSessionCommand(
+ MediaSession2.this, controllerInfo, command, args);
+ } catch (RuntimeException e) {
+ // Controller may be died prematurely.
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
/**
@@ -327,7 +393,7 @@ public class MediaSession2 implements AutoCloseable {
*
* This API is not generally intended for third party application developers.
*/
- static final class ControllerInfo {
+ public static final class ControllerInfo {
private final RemoteUserInfo mRemoteUserInfo;
private final boolean mIsTrusted;
private final Controller2Link mControllerBinder;
@@ -373,36 +439,6 @@ public class MediaSession2 implements AutoCloseable {
return mRemoteUserInfo.getUid();
}
- public void notifyConnected(Bundle connectionResult) {
- if (mControllerBinder != null) {
- try {
- mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult);
- } catch (RuntimeException e) {
- // Controller may be died prematurely.
- }
- }
- }
-
- public void notifyDisconnected() {
- if (mControllerBinder != null) {
- try {
- mControllerBinder.notifyDisconnected(getNextSeqNumber());
- } catch (RuntimeException e) {
- // Controller may be died prematurely.
- }
- }
- }
-
- public void sendSessionCommand(Session2Command command, Bundle args) {
- if (mControllerBinder != null) {
- try {
- mControllerBinder.sendSessionCommand(getNextSeqNumber(), command, args);
- } catch (RuntimeException e) {
- // Controller may be died prematurely.
- }
- }
- }
-
/**
* Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
* has a enabled notification listener so can be trusted to accept connection and incoming
@@ -441,6 +477,36 @@ public class MediaSession2 implements AutoCloseable {
+ mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})";
}
+ void notifyConnected(Bundle connectionResult) {
+ if (mControllerBinder != null) {
+ try {
+ mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult);
+ } catch (RuntimeException e) {
+ // Controller may be died prematurely.
+ }
+ }
+ }
+
+ void notifyDisconnected() {
+ if (mControllerBinder != null) {
+ try {
+ mControllerBinder.notifyDisconnected(getNextSeqNumber());
+ } catch (RuntimeException e) {
+ // Controller may be died prematurely.
+ }
+ }
+ }
+
+ void sendSessionCommand(Session2Command command, Bundle args) {
+ if (mControllerBinder != null) {
+ try {
+ mControllerBinder.sendSessionCommand(getNextSeqNumber(), command, args);
+ } catch (RuntimeException e) {
+ // Controller may be died prematurely.
+ }
+ }
+ }
+
private synchronized int getNextSeqNumber() {
return mNextSeqNumber++;
}