101fe661ae5da3739215d93922412df4b24c859a2RoboErik/* 201fe661ae5da3739215d93922412df4b24c859a2RoboErik * Copyright (C) 2014 The Android Open Source Project 301fe661ae5da3739215d93922412df4b24c859a2RoboErik * 401fe661ae5da3739215d93922412df4b24c859a2RoboErik * Licensed under the Apache License, Version 2.0 (the "License"); 501fe661ae5da3739215d93922412df4b24c859a2RoboErik * you may not use this file except in compliance with the License. 601fe661ae5da3739215d93922412df4b24c859a2RoboErik * You may obtain a copy of the License at 701fe661ae5da3739215d93922412df4b24c859a2RoboErik * 801fe661ae5da3739215d93922412df4b24c859a2RoboErik * http://www.apache.org/licenses/LICENSE-2.0 901fe661ae5da3739215d93922412df4b24c859a2RoboErik * 1001fe661ae5da3739215d93922412df4b24c859a2RoboErik * Unless required by applicable law or agreed to in writing, software 1101fe661ae5da3739215d93922412df4b24c859a2RoboErik * distributed under the License is distributed on an "AS IS" BASIS, 1201fe661ae5da3739215d93922412df4b24c859a2RoboErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1301fe661ae5da3739215d93922412df4b24c859a2RoboErik * See the License for the specific language governing permissions and 1401fe661ae5da3739215d93922412df4b24c859a2RoboErik * limitations under the License. 1501fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 1601fe661ae5da3739215d93922412df4b24c859a2RoboErik 172f5b057da7d05d5d699a272aa24fd7c97cdda820RoboErikpackage android.media.session; 1801fe661ae5da3739215d93922412df4b24c859a2RoboErik 1976fca4e177e18b591439fdff64b8f5242a5122d0RoboErikimport android.annotation.IntDef; 20c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErikimport android.annotation.NonNull; 21c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErikimport android.annotation.Nullable; 22e34c09daf89fb888fe2638e71758573462d85173RoboErikimport android.app.Activity; 2333983a901176adcc16c820444b667a37e6472243RoboErikimport android.app.PendingIntent; 248b4bffcac996b4083e720310a09d315ca1c4a000RoboErikimport android.content.Context; 2501fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.content.Intent; 26f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Pealimport android.content.pm.ParceledListSlice; 279db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErikimport android.media.AudioAttributes; 283625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErikimport android.media.MediaDescription; 29c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErikimport android.media.MediaMetadata; 308ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.media.Rating; 31ef3c9e9b057a5aac2d0d012e8e6385660478e203RoboErikimport android.media.VolumeProvider; 32c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligandimport android.net.Uri; 3301fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.os.Bundle; 3401fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.os.Handler; 3501fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.os.Looper; 3601fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.os.Message; 37dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brownimport android.os.Parcel; 38dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brownimport android.os.Parcelable; 3901fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.os.RemoteException; 408ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.os.ResultReceiver; 418b4bffcac996b4083e720310a09d315ca1c4a000RoboErikimport android.os.UserHandle; 42b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moonimport android.media.session.MediaSessionManager.RemoteUserInfo; 433625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErikimport android.service.media.MediaBrowserService; 448ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.text.TextUtils; 4501fe661ae5da3739215d93922412df4b24c859a2RoboErikimport android.util.Log; 4621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kimimport android.util.Pair; 47477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErikimport android.view.KeyEvent; 4874d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kimimport android.view.ViewConfiguration; 4901fe661ae5da3739215d93922412df4b24c859a2RoboErik 5076fca4e177e18b591439fdff64b8f5242a5122d0RoboErikimport java.lang.annotation.Retention; 5176fca4e177e18b591439fdff64b8f5242a5122d0RoboErikimport java.lang.annotation.RetentionPolicy; 528ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport java.lang.ref.WeakReference; 5307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport java.util.List; 546edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panickerimport java.util.Objects; 5501fe661ae5da3739215d93922412df4b24c859a2RoboErik 5601fe661ae5da3739215d93922412df4b24c859a2RoboErik/** 5742ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * Allows interaction with media controllers, volume keys, media buttons, and 5842ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * transport controls. 5901fe661ae5da3739215d93922412df4b24c859a2RoboErik * <p> 6001fe661ae5da3739215d93922412df4b24c859a2RoboErik * A MediaSession should be created when an app wants to publish media playback 6142ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * information or handle media keys. In general an app only needs one session 6242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * for all playback, though multiple sessions can be created to provide finer 6342ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * grain controls of media. 6401fe661ae5da3739215d93922412df4b24c859a2RoboErik * <p> 65bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * Once a session is created the owner of the session may pass its 66bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * {@link #getSessionToken() session token} to other processes to allow them to 67bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * create a {@link MediaController} to interact with the session. 6801fe661ae5da3739215d93922412df4b24c859a2RoboErik * <p> 69c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * To receive commands, media keys, and other events a {@link Callback} must be 70477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * set with {@link #setCallback(Callback)} and {@link #setActive(boolean) 71477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * setActive(true)} must be called. 7201fe661ae5da3739215d93922412df4b24c859a2RoboErik * <p> 7301fe661ae5da3739215d93922412df4b24c859a2RoboErik * When an app is finished performing playback it must call {@link #release()} 7401fe661ae5da3739215d93922412df4b24c859a2RoboErik * to clean up the session and notify any controllers. 7501fe661ae5da3739215d93922412df4b24c859a2RoboErik * <p> 76bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * MediaSession objects are thread safe. 7701fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 7842ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikpublic final class MediaSession { 79bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown private static final String TAG = "MediaSession"; 8001fe661ae5da3739215d93922412df4b24c859a2RoboErik 81e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik /** 82a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * Set this flag on the session to indicate that it can handle media button 83a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * events. 8492dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim * @deprecated This flag is no longer used. All media sessions are expected to handle media 8592dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim * button events now. 86a8f951462791a16f47e8c07e552232f31dcefac5RoboErik */ 8792dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim @Deprecated 88a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1 << 0; 89a8f951462791a16f47e8c07e552232f31dcefac5RoboErik 90a8f951462791a16f47e8c07e552232f31dcefac5RoboErik /** 91c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Set this flag on the session to indicate that it handles transport 92477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * control commands through its {@link Callback}. 9392dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim * @deprecated This flag is no longer used. All media sessions are expected to handle transport 9492dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim * controls now. 95a8f951462791a16f47e8c07e552232f31dcefac5RoboErik */ 9692dea33bfebed04533264b06e036d04cc16b9608Jaewan Kim @Deprecated 97a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1; 98a8f951462791a16f47e8c07e552232f31dcefac5RoboErik 99a8f951462791a16f47e8c07e552232f31dcefac5RoboErik /** 100e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * System only flag for a session that needs to have priority over all other 101e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * sessions. This flag ensures this session will receive media button events 102e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * regardless of the current ordering in the system. 103e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * 104e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * @hide 105e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik */ 106a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 1 << 16; 107e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik 108b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon /** 109b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * @hide 110b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon */ 111b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon public static final int INVALID_UID = -1; 112b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 113b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon /** 114b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * @hide 115b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon */ 116b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon public static final int INVALID_PID = -1; 117b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 11876fca4e177e18b591439fdff64b8f5242a5122d0RoboErik /** @hide */ 11976fca4e177e18b591439fdff64b8f5242a5122d0RoboErik @Retention(RetentionPolicy.SOURCE) 12076fca4e177e18b591439fdff64b8f5242a5122d0RoboErik @IntDef(flag = true, value = { 12176fca4e177e18b591439fdff64b8f5242a5122d0RoboErik FLAG_HANDLES_MEDIA_BUTTONS, 12276fca4e177e18b591439fdff64b8f5242a5122d0RoboErik FLAG_HANDLES_TRANSPORT_CONTROLS, 12376fca4e177e18b591439fdff64b8f5242a5122d0RoboErik FLAG_EXCLUSIVE_GLOBAL_PRIORITY }) 12476fca4e177e18b591439fdff64b8f5242a5122d0RoboErik public @interface SessionFlags { } 12576fca4e177e18b591439fdff64b8f5242a5122d0RoboErik 12601fe661ae5da3739215d93922412df4b24c859a2RoboErik private final Object mLock = new Object(); 127b9c87fb4034a4a61b57150000a937aa95927861cRoboErik private final int mMaxBitmapSize; 12801fe661ae5da3739215d93922412df4b24c859a2RoboErik 129dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown private final MediaSession.Token mSessionToken; 130031149cd5f22bd858142633c7a763450f42793f7RoboErik private final MediaController mController; 13107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik private final ISession mBinder; 13201fe661ae5da3739215d93922412df4b24c859a2RoboErik private final CallbackStub mCbStub; 13301fe661ae5da3739215d93922412df4b24c859a2RoboErik 134bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim // Do not change the name of mCallback. Support lib accesses this by using reflection. 135bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim private CallbackMessageHandler mCallback; 136ef3c9e9b057a5aac2d0d012e8e6385660478e203RoboErik private VolumeProvider mVolumeProvider; 137477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private PlaybackState mPlaybackState; 1388ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 139bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown private boolean mActive = false; 14001fe661ae5da3739215d93922412df4b24c859a2RoboErik 14101fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 1428b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * Creates a new session. The session will automatically be registered with 1438b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * the system but will not be published until {@link #setActive(boolean) 1448b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * setActive(true)} is called. You must call {@link #release()} when 1458b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * finished with the session. 1468b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * 1478b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * @param context The context to use to create the session. 1488b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * @param tag A short name for debugging purposes. 1498b4bffcac996b4083e720310a09d315ca1c4a000RoboErik */ 1508b4bffcac996b4083e720310a09d315ca1c4a000RoboErik public MediaSession(@NonNull Context context, @NonNull String tag) { 1518b4bffcac996b4083e720310a09d315ca1c4a000RoboErik this(context, tag, UserHandle.myUserId()); 1528b4bffcac996b4083e720310a09d315ca1c4a000RoboErik } 1538b4bffcac996b4083e720310a09d315ca1c4a000RoboErik 1548b4bffcac996b4083e720310a09d315ca1c4a000RoboErik /** 1558b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * Creates a new session as the specified user. To create a session as a 1568b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * user other than your own you must hold the 1578b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} 1588b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * permission. 1598b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * 1608b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * @param context The context to use to create the session. 1618b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * @param tag A short name for debugging purposes. 1628b4bffcac996b4083e720310a09d315ca1c4a000RoboErik * @param userId The user id to create the session as. 16301fe661ae5da3739215d93922412df4b24c859a2RoboErik * @hide 16401fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 1658b4bffcac996b4083e720310a09d315ca1c4a000RoboErik public MediaSession(@NonNull Context context, @NonNull String tag, int userId) { 1668b4bffcac996b4083e720310a09d315ca1c4a000RoboErik if (context == null) { 1678b4bffcac996b4083e720310a09d315ca1c4a000RoboErik throw new IllegalArgumentException("context cannot be null."); 1688b4bffcac996b4083e720310a09d315ca1c4a000RoboErik } 1698b4bffcac996b4083e720310a09d315ca1c4a000RoboErik if (TextUtils.isEmpty(tag)) { 1708b4bffcac996b4083e720310a09d315ca1c4a000RoboErik throw new IllegalArgumentException("tag cannot be null or empty"); 1718b4bffcac996b4083e720310a09d315ca1c4a000RoboErik } 172b9c87fb4034a4a61b57150000a937aa95927861cRoboErik mMaxBitmapSize = context.getResources().getDimensionPixelSize( 173b9c87fb4034a4a61b57150000a937aa95927861cRoboErik com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); 174ca58ddf7c82dd0857de0c3d49d7eb87a842ee4ceRoboErik mCbStub = new CallbackStub(this); 1758b4bffcac996b4083e720310a09d315ca1c4a000RoboErik MediaSessionManager manager = (MediaSessionManager) context 1768b4bffcac996b4083e720310a09d315ca1c4a000RoboErik .getSystemService(Context.MEDIA_SESSION_SERVICE); 17701fe661ae5da3739215d93922412df4b24c859a2RoboErik try { 1788b4bffcac996b4083e720310a09d315ca1c4a000RoboErik mBinder = manager.createSession(mCbStub, tag, userId); 1798b4bffcac996b4083e720310a09d315ca1c4a000RoboErik mSessionToken = new Token(mBinder.getController()); 180031149cd5f22bd858142633c7a763450f42793f7RoboErik mController = new MediaController(context, mSessionToken); 18101fe661ae5da3739215d93922412df4b24c859a2RoboErik } catch (RemoteException e) { 1828b4bffcac996b4083e720310a09d315ca1c4a000RoboErik throw new RuntimeException("Remote error creating session.", e); 18301fe661ae5da3739215d93922412df4b24c859a2RoboErik } 18401fe661ae5da3739215d93922412df4b24c859a2RoboErik } 18501fe661ae5da3739215d93922412df4b24c859a2RoboErik 18601fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 187477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Set the callback to receive updates for the MediaSession. This includes 188477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * media button events and transport controls. The caller's thread will be 189477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * used to post updates. 190477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * <p> 191477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Set the callback to null to stop receiving updates. 19201fe661ae5da3739215d93922412df4b24c859a2RoboErik * 19301fe661ae5da3739215d93922412df4b24c859a2RoboErik * @param callback The callback object 19401fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 195477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void setCallback(@Nullable Callback callback) { 196477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik setCallback(callback, null); 19701fe661ae5da3739215d93922412df4b24c859a2RoboErik } 19801fe661ae5da3739215d93922412df4b24c859a2RoboErik 19907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik /** 200477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Set the callback to receive updates for the MediaSession. This includes 201477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * media button events and transport controls. 202477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * <p> 203477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Set the callback to null to stop receiving updates. 20407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik * 20507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik * @param callback The callback to receive updates on. 20607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik * @param handler The handler that events should be posted on. 20707c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik */ 208477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void setCallback(@Nullable Callback callback, @Nullable Handler handler) { 20901fe661ae5da3739215d93922412df4b24c859a2RoboErik synchronized (mLock) { 210bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim if (mCallback != null) { 21162cef488de93888d6f1388b9f8c05a785faafb79Insun Kang // We're updating the callback, clear the session from the old one. 212bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim mCallback.mCallback.mSession = null; 213bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim mCallback.removeCallbacksAndMessages(null); 21462cef488de93888d6f1388b9f8c05a785faafb79Insun Kang } 2155ea924bcdb7d1a796937a315f59db44179bb4181RoboErik if (callback == null) { 216bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim mCallback = null; 2178ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik return; 21801fe661ae5da3739215d93922412df4b24c859a2RoboErik } 21901fe661ae5da3739215d93922412df4b24c859a2RoboErik if (handler == null) { 22001fe661ae5da3739215d93922412df4b24c859a2RoboErik handler = new Handler(); 22101fe661ae5da3739215d93922412df4b24c859a2RoboErik } 2225ea924bcdb7d1a796937a315f59db44179bb4181RoboErik callback.mSession = this; 223c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), 224c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik callback); 225bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim mCallback = msgHandler; 2268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 2278ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 2288ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 2298ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik /** 23033983a901176adcc16c820444b667a37e6472243RoboErik * Set an intent for launching UI for this Session. This can be used as a 231e34c09daf89fb888fe2638e71758573462d85173RoboErik * quick link to an ongoing media screen. The intent should be for an 232e34c09daf89fb888fe2638e71758573462d85173RoboErik * activity that may be started using {@link Activity#startActivity(Intent)}. 23333983a901176adcc16c820444b667a37e6472243RoboErik * 23433983a901176adcc16c820444b667a37e6472243RoboErik * @param pi The intent to launch to show UI for this Session. 23533983a901176adcc16c820444b667a37e6472243RoboErik */ 236d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik public void setSessionActivity(@Nullable PendingIntent pi) { 237e34c09daf89fb888fe2638e71758573462d85173RoboErik try { 238e34c09daf89fb888fe2638e71758573462d85173RoboErik mBinder.setLaunchPendingIntent(pi); 239e34c09daf89fb888fe2638e71758573462d85173RoboErik } catch (RemoteException e) { 240e34c09daf89fb888fe2638e71758573462d85173RoboErik Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e); 241e34c09daf89fb888fe2638e71758573462d85173RoboErik } 24233983a901176adcc16c820444b667a37e6472243RoboErik } 24333983a901176adcc16c820444b667a37e6472243RoboErik 24433983a901176adcc16c820444b667a37e6472243RoboErik /** 245b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik * Set a pending intent for your media button receiver to allow restarting 246b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik * playback after the session has been stopped. If your app is started in 247b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via 248b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik * the pending intent. 2496f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik * 250b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik * @param mbr The {@link PendingIntent} to send the media button event to. 2516f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik */ 252b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { 2536f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik try { 2546f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik mBinder.setMediaButtonReceiver(mbr); 2556f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik } catch (RemoteException e) { 2566f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); 2576f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik } 2586f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik } 2596f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik 2606f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik /** 261a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * Set any flags for the session. 262e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * 263e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik * @param flags The flags to set for this session. 264e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik */ 26576fca4e177e18b591439fdff64b8f5242a5122d0RoboErik public void setFlags(@SessionFlags int flags) { 266e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik try { 267e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik mBinder.setFlags(flags); 268e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik } catch (RemoteException e) { 269e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik Log.wtf(TAG, "Failure in setFlags.", e); 270e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik } 271e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik } 272e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik 273e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik /** 2749db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * Set the attributes for this session's audio. This will affect the 2759db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * system's volume handling for this session. If 2769db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * {@link #setPlaybackToRemote} was previously called it will stop receiving 2779db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * volume commands and the system will begin sending volume changes to the 2789db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * appropriate stream. 27933983a901176adcc16c820444b667a37e6472243RoboErik * <p> 2809db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * By default sessions use attributes for media. 28133983a901176adcc16c820444b667a37e6472243RoboErik * 2829db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * @param attributes The {@link AudioAttributes} for this session's audio. 28333983a901176adcc16c820444b667a37e6472243RoboErik */ 2849db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik public void setPlaybackToLocal(AudioAttributes attributes) { 2859db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik if (attributes == null) { 2869db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik throw new IllegalArgumentException("Attributes cannot be null for local playback."); 2879db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik } 288b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik try { 2899db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik mBinder.setPlaybackToLocal(attributes); 290b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } catch (RemoteException e) { 291b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik Log.wtf(TAG, "Failure in setPlaybackToLocal.", e); 292b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 29333983a901176adcc16c820444b667a37e6472243RoboErik } 29433983a901176adcc16c820444b667a37e6472243RoboErik 29533983a901176adcc16c820444b667a37e6472243RoboErik /** 29633983a901176adcc16c820444b667a37e6472243RoboErik * Configure this session to use remote volume handling. This must be called 29733983a901176adcc16c820444b667a37e6472243RoboErik * to receive volume button events, otherwise the system will adjust the 2989db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * appropriate stream volume for this session. If 2999db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * {@link #setPlaybackToLocal} was previously called the system will stop 3009db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * handling volume changes for this session and pass them to the volume 3019db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik * provider instead. 30233983a901176adcc16c820444b667a37e6472243RoboErik * 30333983a901176adcc16c820444b667a37e6472243RoboErik * @param volumeProvider The provider that will handle volume changes. May 30433983a901176adcc16c820444b667a37e6472243RoboErik * not be null. 30533983a901176adcc16c820444b667a37e6472243RoboErik */ 306bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) { 30733983a901176adcc16c820444b667a37e6472243RoboErik if (volumeProvider == null) { 30833983a901176adcc16c820444b667a37e6472243RoboErik throw new IllegalArgumentException("volumeProvider may not be null!"); 30933983a901176adcc16c820444b667a37e6472243RoboErik } 310563acea6665c45902bbc46db1a22c036344a818bRoboErik synchronized (mLock) { 311563acea6665c45902bbc46db1a22c036344a818bRoboErik mVolumeProvider = volumeProvider; 312563acea6665c45902bbc46db1a22c036344a818bRoboErik } 313bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown volumeProvider.setCallback(new VolumeProvider.Callback() { 314bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown @Override 315bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void onVolumeChanged(VolumeProvider volumeProvider) { 316bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown notifyRemoteVolumeChanged(volumeProvider); 317bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown } 318bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown }); 319b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik 320b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik try { 3219db9bf7034d7dcdf596dc22d521b18975d0dd2b9RoboErik mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(), 322b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik volumeProvider.getMaxVolume()); 3230d0f67f5ee5f939a1b611bc4583212707afd9beeRoboErik mBinder.setCurrentVolume(volumeProvider.getCurrentVolume()); 324b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } catch (RemoteException e) { 325b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik Log.wtf(TAG, "Failure in setPlaybackToRemote.", e); 326b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 32733983a901176adcc16c820444b667a37e6472243RoboErik } 32833983a901176adcc16c820444b667a37e6472243RoboErik 32933983a901176adcc16c820444b667a37e6472243RoboErik /** 330a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * Set if this session is currently active and ready to receive commands. If 331a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * set to false your session's controller may not be discoverable. You must 332a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * set the session to active before it can start receiving media button 333a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * events or transport commands. 334a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * 335a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * @param active Whether this session is active or not. 3368ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik */ 337a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public void setActive(boolean active) { 338a8f951462791a16f47e8c07e552232f31dcefac5RoboErik if (mActive == active) { 339a8f951462791a16f47e8c07e552232f31dcefac5RoboErik return; 3408ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 3418ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik try { 342a8f951462791a16f47e8c07e552232f31dcefac5RoboErik mBinder.setActive(active); 343a8f951462791a16f47e8c07e552232f31dcefac5RoboErik mActive = active; 3448ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } catch (RemoteException e) { 345a8f951462791a16f47e8c07e552232f31dcefac5RoboErik Log.wtf(TAG, "Failure in setActive.", e); 3468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 347a8f951462791a16f47e8c07e552232f31dcefac5RoboErik } 348a8f951462791a16f47e8c07e552232f31dcefac5RoboErik 349a8f951462791a16f47e8c07e552232f31dcefac5RoboErik /** 350a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * Get the current active state of this session. 351a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * 352a8f951462791a16f47e8c07e552232f31dcefac5RoboErik * @return True if the session is active, false otherwise. 353a8f951462791a16f47e8c07e552232f31dcefac5RoboErik */ 354a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public boolean isActive() { 355a8f951462791a16f47e8c07e552232f31dcefac5RoboErik return mActive; 3568ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 3578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 3588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik /** 3598ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Send a proprietary event to all MediaControllers listening to this 3608ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Session. It's up to the Controller/Session owner to determine the meaning 3618ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * of any events. 36201fe661ae5da3739215d93922412df4b24c859a2RoboErik * 3638ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * @param event The name of the event to send 3648ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * @param extras Any extras included with the event 36501fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 366bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) { 3678ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (TextUtils.isEmpty(event)) { 3688ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik throw new IllegalArgumentException("event cannot be null or empty"); 3698ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 37001fe661ae5da3739215d93922412df4b24c859a2RoboErik try { 3718ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mBinder.sendEvent(event, extras); 37201fe661ae5da3739215d93922412df4b24c859a2RoboErik } catch (RemoteException e) { 3738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.wtf(TAG, "Error sending event", e); 37401fe661ae5da3739215d93922412df4b24c859a2RoboErik } 37501fe661ae5da3739215d93922412df4b24c859a2RoboErik } 37601fe661ae5da3739215d93922412df4b24c859a2RoboErik 37701fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 37801fe661ae5da3739215d93922412df4b24c859a2RoboErik * This must be called when an app has finished performing playback. If 37901fe661ae5da3739215d93922412df4b24c859a2RoboErik * playback is expected to start again shortly the session can be left open, 38001fe661ae5da3739215d93922412df4b24c859a2RoboErik * but it must be released if your activity or service is being destroyed. 38101fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 38201fe661ae5da3739215d93922412df4b24c859a2RoboErik public void release() { 38301fe661ae5da3739215d93922412df4b24c859a2RoboErik try { 38401fe661ae5da3739215d93922412df4b24c859a2RoboErik mBinder.destroy(); 38501fe661ae5da3739215d93922412df4b24c859a2RoboErik } catch (RemoteException e) { 3868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.wtf(TAG, "Error releasing session: ", e); 38701fe661ae5da3739215d93922412df4b24c859a2RoboErik } 38801fe661ae5da3739215d93922412df4b24c859a2RoboErik } 38901fe661ae5da3739215d93922412df4b24c859a2RoboErik 39001fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 39101fe661ae5da3739215d93922412df4b24c859a2RoboErik * Retrieve a token object that can be used by apps to create a 39242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * {@link MediaController} for interacting with this session. The owner of 39301fe661ae5da3739215d93922412df4b24c859a2RoboErik * the session is responsible for deciding how to distribute these tokens. 39401fe661ae5da3739215d93922412df4b24c859a2RoboErik * 39501fe661ae5da3739215d93922412df4b24c859a2RoboErik * @return A token that can be used to create a MediaController for this 39601fe661ae5da3739215d93922412df4b24c859a2RoboErik * session 39701fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 398dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public @NonNull Token getSessionToken() { 39901fe661ae5da3739215d93922412df4b24c859a2RoboErik return mSessionToken; 40001fe661ae5da3739215d93922412df4b24c859a2RoboErik } 40101fe661ae5da3739215d93922412df4b24c859a2RoboErik 40207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik /** 403031149cd5f22bd858142633c7a763450f42793f7RoboErik * Get a controller for this session. This is a convenience method to avoid 404031149cd5f22bd858142633c7a763450f42793f7RoboErik * having to cache your own controller in process. 405031149cd5f22bd858142633c7a763450f42793f7RoboErik * 406031149cd5f22bd858142633c7a763450f42793f7RoboErik * @return A controller for this session. 407031149cd5f22bd858142633c7a763450f42793f7RoboErik */ 408031149cd5f22bd858142633c7a763450f42793f7RoboErik public @NonNull MediaController getController() { 409031149cd5f22bd858142633c7a763450f42793f7RoboErik return mController; 410031149cd5f22bd858142633c7a763450f42793f7RoboErik } 411031149cd5f22bd858142633c7a763450f42793f7RoboErik 412031149cd5f22bd858142633c7a763450f42793f7RoboErik /** 413c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Update the current playback state. 414c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * 415c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * @param state The current state of playback 416c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 417bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void setPlaybackState(@Nullable PlaybackState state) { 418477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mPlaybackState = state; 419c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik try { 420c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mBinder.setPlaybackState(state); 421c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } catch (RemoteException e) { 422c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik Log.wtf(TAG, "Dead object in setPlaybackState.", e); 423c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 424c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 425c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 426c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 427c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Update the current metadata. New metadata can be created using 428762194c22da77d9369bce61e972d6b3fc43164c0Jaewan Kim * {@link android.media.MediaMetadata.Builder}. This operation may take time proportional to 429762194c22da77d9369bce61e972d6b3fc43164c0Jaewan Kim * the size of the bitmap to replace large bitmaps with a scaled down copy. 430c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * 431c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * @param metadata The new metadata 432762194c22da77d9369bce61e972d6b3fc43164c0Jaewan Kim * @see android.media.MediaMetadata.Builder#putBitmap 433c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 434bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void setMetadata(@Nullable MediaMetadata metadata) { 435762194c22da77d9369bce61e972d6b3fc43164c0Jaewan Kim if (metadata != null) { 436f32bd3c5cd8bd2c00f52ea32d7481c30e29d2accMichael Wright metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build(); 437f32bd3c5cd8bd2c00f52ea32d7481c30e29d2accMichael Wright } 438c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik try { 439c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mBinder.setMetadata(metadata); 440c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } catch (RemoteException e) { 441c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik Log.wtf(TAG, "Dead object in setPlaybackState.", e); 442c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 443c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 444c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 4455d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik /** 446a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * Update the list of items in the play queue. It is an ordered list and 447a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * should contain the current item, and previous or upcoming items if they 448a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * exist. Specify null if there is no current play queue. 449f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * <p> 450a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * The queue should be of reasonable size. If the play queue is unbounded 451a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * within your app, it is better to send a reasonable amount in a sliding 452a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * window instead. 453f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * 454a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * @param queue A list of items in the play queue. 455f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 4563625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public void setQueue(@Nullable List<QueueItem> queue) { 457f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal try { 45803fce072cac092923e10a6b5f09fcde333375f9eRoboErik mBinder.setQueue(queue == null ? null : new ParceledListSlice<QueueItem>(queue)); 459f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } catch (RemoteException e) { 460f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal Log.wtf("Dead object in setQueue.", e); 461f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 462f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 463f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 464f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 465f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * Set the title of the play queue. The UI should display this title along 466f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * with the play queue itself. 467f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * e.g. "Play Queue", "Now Playing", or an album name. 468f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * 469f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * @param title The title of the play queue. 470f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 471f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public void setQueueTitle(@Nullable CharSequence title) { 472f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal try { 473f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal mBinder.setQueueTitle(title); 474f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } catch (RemoteException e) { 475f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal Log.wtf("Dead object in setQueueTitle.", e); 476f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 477f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 478f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 479f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 480566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * Set the style of rating used by this session. Apps trying to set the 481566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * rating should use this style. Must be one of the following: 482566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <ul> 483566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_NONE}</li> 484566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_3_STARS}</li> 485566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_4_STARS}</li> 486566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_5_STARS}</li> 487566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_HEART}</li> 488566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_PERCENTAGE}</li> 489566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li> 490566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik * </ul> 491566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik */ 4927c090d54e2c0eb5309d3f7dc131e137d9c986793Insun Kang public void setRatingType(@Rating.Style int type) { 493566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik try { 494566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik mBinder.setRatingType(type); 495566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik } catch (RemoteException e) { 496566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik Log.e(TAG, "Error in setRatingType.", e); 497566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik } 498566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik } 499566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik 500566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik /** 501f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * Set some extras that can be associated with the {@link MediaSession}. No assumptions should 502f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * be made as to how a {@link MediaController} will handle these extras. 503f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts. 504f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * 505f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * @param extras The extras associated with the {@link MediaSession}. 506f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 507f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public void setExtras(@Nullable Bundle extras) { 508f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal try { 509f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal mBinder.setExtras(extras); 510f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } catch (RemoteException e) { 511f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal Log.wtf("Dead object in setExtras.", e); 512f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 513f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 514f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 515f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 516b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * Gets the controller information who sent the current request. 517b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * <p> 518b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * Note: This is only valid while in a request callback, such as {@link Callback#onPlay}. 519b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * 520b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * @throws IllegalStateException If this method is called outside of {@link Callback} methods. 521b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo) 522b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon */ 523b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon public final @NonNull RemoteUserInfo getCurrentControllerInfo() { 52421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim if (mCallback == null || mCallback.mCurrentControllerInfo == null) { 525b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon throw new IllegalStateException( 526b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon "This should be called inside of MediaSession.Callback methods"); 527b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon } 52821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim return mCallback.mCurrentControllerInfo; 529b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon } 530b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 531b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon /** 532ef3c9e9b057a5aac2d0d012e8e6385660478e203RoboErik * Notify the system that the remote volume changed. 5335d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik * 5345d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik * @param provider The provider that is handling volume changes. 5355d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik * @hide 5365d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik */ 537ef3c9e9b057a5aac2d0d012e8e6385660478e203RoboErik public void notifyRemoteVolumeChanged(VolumeProvider provider) { 538563acea6665c45902bbc46db1a22c036344a818bRoboErik synchronized (mLock) { 539563acea6665c45902bbc46db1a22c036344a818bRoboErik if (provider == null || provider != mVolumeProvider) { 540563acea6665c45902bbc46db1a22c036344a818bRoboErik Log.w(TAG, "Received update from stale volume provider"); 541563acea6665c45902bbc46db1a22c036344a818bRoboErik return; 542563acea6665c45902bbc46db1a22c036344a818bRoboErik } 5435d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } 5445d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik try { 5450d0f67f5ee5f939a1b611bc4583212707afd9beeRoboErik mBinder.setCurrentVolume(provider.getCurrentVolume()); 5465d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } catch (RemoteException e) { 5475d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik Log.e(TAG, "Error in notifyVolumeChanged", e); 5485d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } 5495d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } 5505d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik 5511ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho /** 5521ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho * Returns the name of the package that sent the last media button, transport control, or 5531ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho * command from controllers and the system. This is only valid while in a request callback, such 5541ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho * as {@link Callback#onPlay}. 5551ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho * 5561ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho * @hide 5571ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho */ 5581ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho public String getCallingPackage() { 55921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim if (mCallback != null && mCallback.mCurrentControllerInfo != null) { 56021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim return mCallback.mCurrentControllerInfo.getPackageName(); 5611ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho } 5621ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho return null; 5631ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho } 5641ea56832178b40ce5a54ee77e6a01108496dc6e9Donghyun Cho 56521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPrepare(RemoteUserInfo caller) { 56621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null); 56722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 56822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 56921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { 57021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras); 57122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 57222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 57321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) { 57421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras); 57522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 57622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 57721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { 57821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras); 57922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 58022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 58121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPlay(RemoteUserInfo caller) { 58221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null); 583c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 584c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 58521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { 58621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras); 587f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 588f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 58921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) { 59021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); 591f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 592f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 59321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { 59421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras); 595c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand } 596c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand 59721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchSkipToItem(RemoteUserInfo caller, long id) { 59821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null); 599f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 600f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 60121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPause(RemoteUserInfo caller) { 60221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null); 603c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 604c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 60521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchStop(RemoteUserInfo caller) { 60621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null); 607c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 608c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 60921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchNext(RemoteUserInfo caller) { 61021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null); 611c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 612c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 61321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchPrevious(RemoteUserInfo caller) { 61421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null); 615c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 616c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 61721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchFastForward(RemoteUserInfo caller) { 61821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null); 619c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 620c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 62121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchRewind(RemoteUserInfo caller) { 62221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null); 623c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 624c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 62521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchSeekTo(RemoteUserInfo caller, long pos) { 62621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null); 627c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 628c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 62921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchRate(RemoteUserInfo caller, Rating rating) { 63021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null); 631c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 632c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 63321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) { 63421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); 635c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 636c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 63721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) { 63821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null); 6398ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 6408ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 64121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent, 64221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim long delay) { 64321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, 64421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mediaButtonIntent, null, delay); 645563acea6665c45902bbc46db1a22c036344a818bRoboErik } 646563acea6665c45902bbc46db1a22c036344a818bRoboErik 64721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchAdjustVolume(RemoteUserInfo caller, int direction) { 64821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null); 649563acea6665c45902bbc46db1a22c036344a818bRoboErik } 650563acea6665c45902bbc46db1a22c036344a818bRoboErik 65121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) { 65221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null); 65321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 65421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim 65521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void dispatchCommand(RemoteUserInfo caller, String command, Bundle args, 65621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ResultReceiver resultCb) { 657f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal Command cmd = new Command(command, args, resultCb); 65821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null); 65901fe661ae5da3739215d93922412df4b24c859a2RoboErik } 66001fe661ae5da3739215d93922412df4b24c859a2RoboErik 66121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) { 66221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim postToCallbackDelayed(caller, what, obj, data, 0); 66321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 66421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim 66521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data, 66621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim long delay) { 66701fe661ae5da3739215d93922412df4b24c859a2RoboErik synchronized (mLock) { 668bdcb3080b4c061a02a1a0a02f9afe20c1d29cf8aSungsoo Lim if (mCallback != null) { 66921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.post(caller, what, obj, data, delay); 67001fe661ae5da3739215d93922412df4b24c859a2RoboErik } 67101fe661ae5da3739215d93922412df4b24c859a2RoboErik } 67201fe661ae5da3739215d93922412df4b24c859a2RoboErik } 67301fe661ae5da3739215d93922412df4b24c859a2RoboErik 67401fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 6753c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik * Return true if this is considered an active playback state. 6763c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik * 6773c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik * @hide 6783c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik */ 6793c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik public static boolean isActiveState(int state) { 6803c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik switch (state) { 6813c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_FAST_FORWARDING: 6823c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_REWINDING: 6833c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: 6843c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_SKIPPING_TO_NEXT: 6853c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_BUFFERING: 6863c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_CONNECTING: 6873c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik case PlaybackState.STATE_PLAYING: 6883c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik return true; 6893c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik } 6903c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik return false; 6913c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik } 6923c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik 6933c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik /** 694dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown * Represents an ongoing session. This may be passed to apps by the session 695dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown * owner to allow them to create a {@link MediaController} to communicate with 696dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown * the session. 697dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown */ 698dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public static final class Token implements Parcelable { 699aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik 700dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown private ISessionController mBinder; 701dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 702dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown /** 703dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown * @hide 704dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown */ 705dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public Token(ISessionController binder) { 706dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown mBinder = binder; 707dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 708dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 709dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown @Override 710dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public int describeContents() { 711dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown return 0; 712dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 713dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 714dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown @Override 715dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public void writeToParcel(Parcel dest, int flags) { 716dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown dest.writeStrongBinder(mBinder.asBinder()); 717dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 718dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 719aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik @Override 720aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik public int hashCode() { 721aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik final int prime = 31; 722aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik int result = 1; 723aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik result = prime * result + ((mBinder == null) ? 0 : mBinder.asBinder().hashCode()); 724aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return result; 725aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik } 726aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik 727aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik @Override 728aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik public boolean equals(Object obj) { 729aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik if (this == obj) 730aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return true; 731aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik if (obj == null) 732aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return false; 733aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik if (getClass() != obj.getClass()) 734aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return false; 735aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik Token other = (Token) obj; 736aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik if (mBinder == null) { 737aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik if (other.mBinder != null) 738aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return false; 739aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik } else if (!mBinder.asBinder().equals(other.mBinder.asBinder())) 740aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return false; 741aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik return true; 742aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik } 743aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik 744dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown ISessionController getBinder() { 745dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown return mBinder; 746dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 747dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 748dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public static final Parcelable.Creator<Token> CREATOR 749dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown = new Parcelable.Creator<Token>() { 750dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown @Override 751dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public Token createFromParcel(Parcel in) { 752dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown return new Token(ISessionController.Stub.asInterface(in.readStrongBinder())); 753dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 754dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 755dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown @Override 756dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public Token[] newArray(int size) { 757dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown return new Token[size]; 758dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 759dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown }; 760dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown } 761dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown 762dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown /** 763477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Receives media buttons, transport controls, and commands from controllers 764477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * and the system. A callback may be set using {@link #setCallback}. 76501fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 76601fe661ae5da3739215d93922412df4b24c859a2RoboErik public abstract static class Callback { 767b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 768477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private MediaSession mSession; 76974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim private CallbackMessageHandler mHandler; 77074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim private boolean mMediaPlayPauseKeyPending; 77101fe661ae5da3739215d93922412df4b24c859a2RoboErik 77201fe661ae5da3739215d93922412df4b24c859a2RoboErik public Callback() { 77301fe661ae5da3739215d93922412df4b24c859a2RoboErik } 77401fe661ae5da3739215d93922412df4b24c859a2RoboErik 77501fe661ae5da3739215d93922412df4b24c859a2RoboErik /** 776f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * Called when a controller has sent a command to this session. 77701fe661ae5da3739215d93922412df4b24c859a2RoboErik * The owner of the session may handle custom commands but is not 77801fe661ae5da3739215d93922412df4b24c859a2RoboErik * required to. 77901fe661ae5da3739215d93922412df4b24c859a2RoboErik * 780bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * @param command The command name. 781f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * @param args Optional parameters for the command, may be null. 782bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown * @param cb A result receiver to which a result may be sent by the command, may be null. 78301fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 784f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal public void onCommand(@NonNull String command, @Nullable Bundle args, 785bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown @Nullable ResultReceiver cb) { 78601fe661ae5da3739215d93922412df4b24c859a2RoboErik } 78701fe661ae5da3739215d93922412df4b24c859a2RoboErik 788477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik /** 789477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * Called when a media button is pressed and this session has the 790477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * highest priority or a controller sends a media button event to the 791477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * session. The default behavior will call the relevant method if the 792477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * action for it was set. 793477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * <p> 794477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a 795477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * KeyEvent in {@link Intent#EXTRA_KEY_EVENT} 796477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * 797477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * @param mediaButtonIntent an intent containing the KeyEvent as an 798477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik * extra 799cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik * @return True if the event was handled, false otherwise. 800477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik */ 801477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { 80274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim if (mSession != null && mHandler != null 803477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { 804477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 805477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { 806477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik PlaybackState state = mSession.mPlaybackState; 807477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik long validActions = state == null ? 0 : state.getActions(); 808477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik switch (ke.getKeyCode()) { 80974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 81074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim case KeyEvent.KEYCODE_HEADSETHOOK: 81174d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim if (ke.getRepeatCount() > 0) { 81274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim // Consider long-press as a single tap. 81374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim handleMediaPlayPauseKeySingleTapIfPending(); 81474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } else if (mMediaPlayPauseKeyPending) { 81574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim // Consider double tap as the next. 81674d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mHandler.removeMessages(CallbackMessageHandler 81774d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); 81874d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mMediaPlayPauseKeyPending = false; 81974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { 82074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim onSkipToNext(); 82174d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 82274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } else { 82374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mMediaPlayPauseKeyPending = true; 82421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mSession.dispatchMediaButtonDelayed( 82521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mSession.getCurrentControllerInfo(), 82621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout()); 82774d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 82874d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim return true; 82974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim default: 83074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim // If another key is pressed within double tap timeout, consider the 83174d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim // pending play/pause as a single tap to handle media keys in order. 83274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim handleMediaPlayPauseKeySingleTapIfPending(); 83374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim break; 83474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 83574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim 83674d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim switch (ke.getKeyCode()) { 837477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_PLAY: 838477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_PLAY) != 0) { 839477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onPlay(); 840cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 841477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 842477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 843477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_PAUSE: 844477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { 845477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onPause(); 846cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 847477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 848477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 849477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_NEXT: 850477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { 851477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onSkipToNext(); 852cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 853477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 854477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 855477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 856477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { 857477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onSkipToPrevious(); 858cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 859477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 860477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 861477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_STOP: 862477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_STOP) != 0) { 863477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onStop(); 864cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 865477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 866477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 867477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 868477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { 869477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onFastForward(); 870cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 871477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 872477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 873477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik case KeyEvent.KEYCODE_MEDIA_REWIND: 874477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if ((validActions & PlaybackState.ACTION_REWIND) != 0) { 875477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik onRewind(); 876cd74270da7a7320904f14a465b8902dd5ea56f1dRoboErik return true; 877477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 878477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik break; 879477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 880477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 881477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 882477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik return false; 883477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 884c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 88574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim private void handleMediaPlayPauseKeySingleTapIfPending() { 88674d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim if (!mMediaPlayPauseKeyPending) { 88774d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim return; 88874d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 88974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mMediaPlayPauseKeyPending = false; 89074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); 89174d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim PlaybackState state = mSession.mPlaybackState; 89274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim long validActions = state == null ? 0 : state.getActions(); 89374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim boolean isPlaying = state != null 89474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim && state.getState() == PlaybackState.STATE_PLAYING; 89574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE 89674d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim | PlaybackState.ACTION_PLAY)) != 0; 89774d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE 89874d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim | PlaybackState.ACTION_PAUSE)) != 0; 89974d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim if (isPlaying && canPause) { 90074d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim onPause(); 90174d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } else if (!isPlaying && canPlay) { 90274d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim onPlay(); 90374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 90474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim } 90574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim 906c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 907f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * Override to handle requests to prepare playback. During the preparation, a session should 908f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * not hold audio focus in order to allow other sessions play seamlessly. The state of 909f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * playback should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is 910f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * done. 911c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 91222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPrepare() { 913c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 914c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 915c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 91622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * Override to handle requests to prepare for playing a specific mediaId that was provided 917f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * by your app's {@link MediaBrowserService}. During the preparation, a session should not 918f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * hold audio focus in order to allow other sessions play seamlessly. The state of playback 919f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. 920f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * The playback of the prepared content should start in the implementation of 921f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * {@link #onPlay}. Override {@link #onPlayFromMediaId} to handle requests for starting 922f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * playback without preparation. 923f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 92422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPrepareFromMediaId(String mediaId, Bundle extras) { 92522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 92622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 92722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho /** 928f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * Override to handle requests to prepare playback from a search query. An empty query 929f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * indicates that the app may prepare any music. The implementation should attempt to make a 930f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * smart choice about what to play. During the preparation, a session should not hold audio 931f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * focus in order to allow other sessions play seamlessly. The state of playback should be 932f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback 933f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * of the prepared content should start in the implementation of {@link #onPlay}. Override 934f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * {@link #onPlayFromSearch} to handle requests for starting playback without preparation. 93522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho */ 93622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPrepareFromSearch(String query, Bundle extras) { 93722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 93822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 93922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho /** 94022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * Override to handle requests to prepare a specific media item represented by a URI. 941f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * During the preparation, a session should not hold audio focus in order to allow 942f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * other sessions play seamlessly. The state of playback should be updated to 943f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * {@link PlaybackState#STATE_PAUSED} after the preparation is done. 944f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * The playback of the prepared content should start in the implementation of 945f9f240ab7d9918a14437d3ae63ae959e4ff906ccDonghyun Cho * {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests 94622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * for starting playback without preparation. 94722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho */ 94822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPrepareFromUri(Uri uri, Bundle extras) { 94922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 95022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 95122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho /** 95222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * Override to handle requests to begin playback. 95322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho */ 95422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPlay() { 955f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 956f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 957f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 9584b253d2bcd62ea2a9afb067c1f1363fa7b752185RoboErik * Override to handle requests to begin playback from a search query. An 9594b253d2bcd62ea2a9afb067c1f1363fa7b752185RoboErik * empty query indicates that the app may play any music. The 9604b253d2bcd62ea2a9afb067c1f1363fa7b752185RoboErik * implementation should attempt to make a smart choice about what to 9614b253d2bcd62ea2a9afb067c1f1363fa7b752185RoboErik * play. 962f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 963f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public void onPlayFromSearch(String query, Bundle extras) { 964f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 965f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 966f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 96722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * Override to handle requests to play a specific mediaId that was 96822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho * provided by your app's {@link MediaBrowserService}. 96922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho */ 97022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho public void onPlayFromMediaId(String mediaId, Bundle extras) { 97122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 97222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 97322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho /** 974c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand * Override to handle requests to play a specific media item represented by a URI. 975c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand */ 976c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand public void onPlayFromUri(Uri uri, Bundle extras) { 977c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand } 978c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand 979c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand /** 980a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * Override to handle requests to play an item with a given id from the 981a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * play queue. 982f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 9833625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public void onSkipToQueueItem(long id) { 984f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 985f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 986f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 987c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to pause playback. 988c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 989c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onPause() { 990c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 991c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 992c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 993c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to skip to the next media item. 994c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 995c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onSkipToNext() { 996c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 997c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 998c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 999c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to skip to the previous media item. 1000c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1001c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onSkipToPrevious() { 1002c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1003c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1004c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 1005c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to fast forward. 1006c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1007c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onFastForward() { 1008c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1009c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1010c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 1011c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to rewind. 1012c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1013c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onRewind() { 1014c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1015c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1016c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 1017c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to stop playback. 1018c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1019c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onStop() { 1020c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1021c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1022c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 1023c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle requests to seek to a specific position in ms. 1024c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * 1025c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * @param pos New position to move to, in milliseconds. 1026c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1027c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void onSeekTo(long pos) { 1028c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1029c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1030c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 1031c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * Override to handle the item being rated. 1032c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * 1033c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik * @param rating 1034c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik */ 1035bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown public void onSetRating(@NonNull Rating rating) { 1036c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1037f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal 1038f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal /** 1039f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be 1040f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * performed. 1041f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * 1042f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * @param action The action that was originally sent in the 1043f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * {@link PlaybackState.CustomAction}. 1044f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal * @param extras Optional extras specified by the {@link MediaController}. 1045f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal */ 1046f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { 1047f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal } 1048c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1049c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1050c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik /** 105101fe661ae5da3739215d93922412df4b24c859a2RoboErik * @hide 105201fe661ae5da3739215d93922412df4b24c859a2RoboErik */ 105307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public static class CallbackStub extends ISessionCallback.Stub { 105442ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private WeakReference<MediaSession> mMediaSession; 105501fe661ae5da3739215d93922412df4b24c859a2RoboErik 1056ca58ddf7c82dd0857de0c3d49d7eb87a842ee4ceRoboErik public CallbackStub(MediaSession session) { 1057b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon mMediaSession = new WeakReference<>(session); 105801fe661ae5da3739215d93922412df4b24c859a2RoboErik } 105901fe661ae5da3739215d93922412df4b24c859a2RoboErik 106021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid, 106121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 106221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim return new RemoteUserInfo(packageName, pid, uid, 106321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim caller != null ? caller.asBinder() : null); 106421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 106521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim 106601fe661ae5da3739215d93922412df4b24c859a2RoboErik @Override 106721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onCommand(String packageName, int pid, int uid, 106821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) { 106942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 10708ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 107121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid, caller), 107221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim command, args, cb); 10738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 107401fe661ae5da3739215d93922412df4b24c859a2RoboErik } 107501fe661ae5da3739215d93922412df4b24c859a2RoboErik 107601fe661ae5da3739215d93922412df4b24c859a2RoboErik @Override 1077b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent, 1078b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon int sequenceNumber, ResultReceiver cb) { 107942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 1080418c10ca9df1505509afeffd558cd92fc97bc635RoboErik try { 1081418c10ca9df1505509afeffd558cd92fc97bc635RoboErik if (session != null) { 108221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, null), 108321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mediaButtonIntent); 1084418c10ca9df1505509afeffd558cd92fc97bc635RoboErik } 1085418c10ca9df1505509afeffd558cd92fc97bc635RoboErik } finally { 1086418c10ca9df1505509afeffd558cd92fc97bc635RoboErik if (cb != null) { 1087418c10ca9df1505509afeffd558cd92fc97bc635RoboErik cb.send(sequenceNumber, null); 1088418c10ca9df1505509afeffd558cd92fc97bc635RoboErik } 10898a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 109001fe661ae5da3739215d93922412df4b24c859a2RoboErik } 109101fe661ae5da3739215d93922412df4b24c859a2RoboErik 109201fe661ae5da3739215d93922412df4b24c859a2RoboErik @Override 109321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onMediaButtonFromController(String packageName, int pid, int uid, 109421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, Intent mediaButtonIntent) { 109522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho MediaSession session = mMediaSession.get(); 109622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho if (session != null) { 109721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, caller), 109821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mediaButtonIntent); 109922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 110022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 110122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 110222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho @Override 110321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPrepare(String packageName, int pid, int uid, 110421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 110521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim MediaSession session = mMediaSession.get(); 110621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim if (session != null) { 110721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid, caller)); 110821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 110921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 111021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim 111121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim @Override 111221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPrepareFromMediaId(String packageName, int pid, int uid, 111321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String mediaId, 1114b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon Bundle extras) { 111522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho MediaSession session = mMediaSession.get(); 111622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho if (session != null) { 1117b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon session.dispatchPrepareFromMediaId( 111821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim createRemoteUserInfo(packageName, pid, uid, caller), mediaId, extras); 111922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 112022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 112122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 112222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho @Override 112321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPrepareFromSearch(String packageName, int pid, int uid, 112421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String query, 1125b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon Bundle extras) { 112622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho MediaSession session = mMediaSession.get(); 112722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho if (session != null) { 1128b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon session.dispatchPrepareFromSearch( 112921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim createRemoteUserInfo(packageName, pid, uid, caller), query, extras); 113022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 113122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 113222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 113322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho @Override 113421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPrepareFromUri(String packageName, int pid, int uid, 113521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, Uri uri, Bundle extras) { 113622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho MediaSession session = mMediaSession.get(); 113722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho if (session != null) { 113821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid, caller), 113921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim uri, extras); 114022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 114122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho } 114222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho 114322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho @Override 114421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPlay(String packageName, int pid, int uid, 114521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 114642ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 11478ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 114821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid, caller)); 11498ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 11508ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 11518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 11528ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 115321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPlayFromMediaId(String packageName, int pid, int uid, 115421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String mediaId, 1155b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon Bundle extras) { 1156f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal MediaSession session = mMediaSession.get(); 1157f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal if (session != null) { 115821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid, caller), 115921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mediaId, extras); 1160f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1161f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1162f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1163f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 116421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPlayFromSearch(String packageName, int pid, int uid, 116521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String query, 1166b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon Bundle extras) { 1167f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal MediaSession session = mMediaSession.get(); 1168f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal if (session != null) { 116921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid, caller), 117021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim query, extras); 1171f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1172f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1173f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1174f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 117521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPlayFromUri(String packageName, int pid, int uid, 117621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, Uri uri, Bundle extras) { 1177c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand MediaSession session = mMediaSession.get(); 1178c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand if (session != null) { 117921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid, caller), 118021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim uri, extras); 1181c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand } 1182c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand } 1183c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand 1184c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand @Override 118521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onSkipToTrack(String packageName, int pid, int uid, 118621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, long id) { 1187f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal MediaSession session = mMediaSession.get(); 1188f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal if (session != null) { 118921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid, caller), id); 1190f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1191f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1192f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1193f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 119421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPause(String packageName, int pid, int uid, 119521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 119642ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 11978ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 119821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPause(createRemoteUserInfo(packageName, pid, uid, caller)); 11998ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12008ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12018ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12028ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 120321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onStop(String packageName, int pid, int uid, 120421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 120542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12068ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 120721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchStop(createRemoteUserInfo(packageName, pid, uid, caller)); 12088ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12098ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12118ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 121221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onNext(String packageName, int pid, int uid, 121321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 121442ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12158ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 121621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchNext(createRemoteUserInfo(packageName, pid, uid, caller)); 12178ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12188ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12198ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12208ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 122121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onPrevious(String packageName, int pid, int uid, 122221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 122342ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12248ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 122521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid, caller)); 12268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12278ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12288ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12298ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 123021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onFastForward(String packageName, int pid, int uid, 123121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 123242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12338ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 123421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid, caller)); 12358ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12368ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12378ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12388ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 123921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onRewind(String packageName, int pid, int uid, 124021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller) { 124142ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12428ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 124321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid, caller)); 12448ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12458ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12478ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 124821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onSeekTo(String packageName, int pid, int uid, 124921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, long pos) { 125042ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 125221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid, caller), pos); 12538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12548ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 12558ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 12568ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 125721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller, 125821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim Rating rating) { 125942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSession session = mMediaSession.get(); 12608ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (session != null) { 126121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchRate(createRemoteUserInfo(packageName, pid, uid, caller), rating); 12628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 126301fe661ae5da3739215d93922412df4b24c859a2RoboErik } 126401fe661ae5da3739215d93922412df4b24c859a2RoboErik 126507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik @Override 126621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onCustomAction(String packageName, int pid, int uid, 126721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, String action, Bundle args) { 1268f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal MediaSession session = mMediaSession.get(); 1269f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal if (session != null) { 127021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid, caller), 127121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim action, args); 1272f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal } 1273f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal } 1274f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal 1275f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal @Override 127621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onAdjustVolume(String packageName, int pid, int uid, 127721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, int direction) { 12785d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik MediaSession session = mMediaSession.get(); 12795d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik if (session != null) { 128021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid, caller), 128121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim direction); 12825d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } 1283b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 1284b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik 1285b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik @Override 128621c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void onSetVolumeTo(String packageName, int pid, int uid, 128721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim ISessionControllerCallback caller, int value) { 12885d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik MediaSession session = mMediaSession.get(); 12895d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik if (session != null) { 129021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid, caller), 129121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim value); 12925d3114b64a88ac1f72becd8d46f148c666f64aa3RoboErik } 1293b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 129401fe661ae5da3739215d93922412df4b24c859a2RoboErik } 129501fe661ae5da3739215d93922412df4b24c859a2RoboErik 1296f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 12973625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * A single item that is part of the play queue. It contains a description 12983625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * of the item and its id in the queue. 1299f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 13003625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public static final class QueueItem implements Parcelable { 1301f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 13023e5a34ea8e90e013c7edd39675746130a6eea954Sungsoo * This id is reserved. No items can be explicitly assigned this id. 1303f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 1304f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public static final int UNKNOWN_ID = -1; 1305f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 13063625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik private final MediaDescription mDescription; 1307f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal private final long mId; 1308f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1309f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 13103625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * Create a new {@link MediaSession.QueueItem}. 1311f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal * 13123625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * @param description The {@link MediaDescription} for this item. 1313a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik * @param id An identifier for this item. It must be unique within the 13143625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * play queue and cannot be {@link #UNKNOWN_ID}. 1315f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 13163625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public QueueItem(MediaDescription description, long id) { 13173625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik if (description == null) { 13183625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik throw new IllegalArgumentException("Description cannot be null."); 13193625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik } 13203625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik if (id == UNKNOWN_ID) { 13213625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID"); 13223625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik } 13233625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik mDescription = description; 1324f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal mId = id; 1325f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1326f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 13273625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik private QueueItem(Parcel in) { 13283625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik mDescription = MediaDescription.CREATOR.createFromParcel(in); 1329f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal mId = in.readLong(); 1330f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1331f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1332f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 13333625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * Get the description for this item. 1334f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 13353625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public MediaDescription getDescription() { 13363625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik return mDescription; 1337f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1338f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1339f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal /** 13403625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik * Get the queue id for this item. 1341f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal */ 13423625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public long getQueueId() { 1343f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal return mId; 1344f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1345f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1346f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 1347f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public void writeToParcel(Parcel dest, int flags) { 13483625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik mDescription.writeToParcel(dest, flags); 1349f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal dest.writeLong(mId); 1350f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1351f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1352f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 1353f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public int describeContents() { 1354f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal return 0; 1355f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1356f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1357b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon public static final Creator<MediaSession.QueueItem> CREATOR = 1358b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon new Creator<MediaSession.QueueItem>() { 1359f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1360f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 13613625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public MediaSession.QueueItem createFromParcel(Parcel p) { 13623625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik return new MediaSession.QueueItem(p); 1363f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1364f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1365f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 13663625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik public MediaSession.QueueItem[] newArray(int size) { 13673625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik return new MediaSession.QueueItem[size]; 1368f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1369f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal }; 1370f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 1371f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal @Override 1372f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal public String toString() { 13733625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik return "MediaSession.QueueItem {" + 13743625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik "Description=" + mDescription + 13753625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik ", Id=" + mId + " }"; 1376f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 13776edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker 13786edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker @Override 13796edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker public boolean equals(Object o) { 13806edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker if (o == null) { 13816edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker return false; 13826edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker } 13836edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker 13846edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker if (!(o instanceof QueueItem)) { 13856edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker return false; 13866edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker } 13876edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker 13886edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker final QueueItem item = (QueueItem) o; 13896edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker if (mId != item.mId) { 13906edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker return false; 13916edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker } 13926edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker 13936edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker if (!Objects.equals(mDescription, item.mDescription)) { 13946edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker return false; 13956edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker } 13966edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker 13976edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker return true; 13986edb68bea68d5f324384f3e9e411118eb8dfc781Ajay Panicker } 1399f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal } 1400f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal 14018ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private static final class Command { 14028ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public final String command; 14038ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public final Bundle extras; 14048ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public final ResultReceiver stub; 14058ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 14068ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public Command(String command, Bundle extras, ResultReceiver stub) { 14078ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik this.command = command; 14088ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik this.extras = extras; 14098ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik this.stub = stub; 14108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 141101fe661ae5da3739215d93922412df4b24c859a2RoboErik } 1412c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1413477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private class CallbackMessageHandler extends Handler { 141422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_COMMAND = 1; 141522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_MEDIA_BUTTON = 2; 141622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PREPARE = 3; 141722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PREPARE_MEDIA_ID = 4; 141822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PREPARE_SEARCH = 5; 141922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PREPARE_URI = 6; 142022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PLAY = 7; 142122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PLAY_MEDIA_ID = 8; 142222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PLAY_SEARCH = 9; 142322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PLAY_URI = 10; 142422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_SKIP_TO_ITEM = 11; 142522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PAUSE = 12; 142622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_STOP = 13; 142722188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_NEXT = 14; 142822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_PREVIOUS = 15; 142922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_FAST_FORWARD = 16; 143022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_REWIND = 17; 143122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_SEEK_TO = 18; 143222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho private static final int MSG_RATE = 19; 14333e5a34ea8e90e013c7edd39675746130a6eea954Sungsoo private static final int MSG_CUSTOM_ACTION = 20; 14343e5a34ea8e90e013c7edd39675746130a6eea954Sungsoo private static final int MSG_ADJUST_VOLUME = 21; 14353e5a34ea8e90e013c7edd39675746130a6eea954Sungsoo private static final int MSG_SET_VOLUME = 22; 143674d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23; 1437c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 1438477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private MediaSession.Callback mCallback; 143921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim private RemoteUserInfo mCurrentControllerInfo; 1440b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 1441477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { 1442477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik super(looper, null, true); 1443477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mCallback = callback; 144474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mCallback.mHandler = this; 1445c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1446c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik 144721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim public void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) { 144821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj); 144921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim Message msg = obtainMessage(what, objWithCaller); 145077748b623c893f3c11714580d1a99fae934185ffJaewan Kim msg.setData(data); 145121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim if (delayMs > 0) { 145221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim sendMessageDelayed(msg, delayMs); 145321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } else { 145421c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim sendMessage(msg); 145521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim } 145677748b623c893f3c11714580d1a99fae934185ffJaewan Kim } 145777748b623c893f3c11714580d1a99fae934185ffJaewan Kim 1458c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik @Override 1459c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik public void handleMessage(Message msg) { 146021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first; 1461b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 146221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim VolumeProvider vp; 146321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second; 1464b1e344eaab519aa9bc9db20c891831dfe2bf92abHyundo Moon 1465c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik switch (msg.what) { 146622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_COMMAND: 146721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim Command cmd = (Command) obj; 146822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); 146922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 147022188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_MEDIA_BUTTON: 147121c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onMediaButtonEvent((Intent) obj); 147222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 147322188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_PREPARE: 147422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho mCallback.onPrepare(); 147522188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 147622188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_PREPARE_MEDIA_ID: 147721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPrepareFromMediaId((String) obj, msg.getData()); 147822188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 147922188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_PREPARE_SEARCH: 148021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPrepareFromSearch((String) obj, msg.getData()); 148122188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 148222188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho case MSG_PREPARE_URI: 148321c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPrepareFromUri((Uri) obj, msg.getData()); 148422188f118754c3b31c13d2f94daf718f111d92afDonghyun Cho break; 1485c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_PLAY: 1486c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onPlay(); 1487c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 14883625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik case MSG_PLAY_MEDIA_ID: 148921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPlayFromMediaId((String) obj, msg.getData()); 1490f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal break; 1491f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal case MSG_PLAY_SEARCH: 149221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPlayFromSearch((String) obj, msg.getData()); 1493f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal break; 1494c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand case MSG_PLAY_URI: 149521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onPlayFromUri((Uri) obj, msg.getData()); 1496c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand break; 1497a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik case MSG_SKIP_TO_ITEM: 149821c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onSkipToQueueItem((Long) obj); 149959759903a9696daefa817079c8432468ed398033RoboErik break; 1500c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_PAUSE: 1501c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onPause(); 1502c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1503c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_STOP: 1504c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onStop(); 1505c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1506c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_NEXT: 1507c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onSkipToNext(); 1508c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1509c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_PREVIOUS: 1510c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onSkipToPrevious(); 1511c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1512c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_FAST_FORWARD: 1513c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onFastForward(); 1514c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1515c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_REWIND: 1516c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mCallback.onRewind(); 1517c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1518c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_SEEK_TO: 151921c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onSeekTo((Long) obj); 1520c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1521c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik case MSG_RATE: 152221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onSetRating((Rating) obj); 1523c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik break; 1524f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal case MSG_CUSTOM_ACTION: 152521c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCallback.onCustomAction((String) obj, msg.getData()); 1526f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal break; 1527563acea6665c45902bbc46db1a22c036344a818bRoboErik case MSG_ADJUST_VOLUME: 1528563acea6665c45902bbc46db1a22c036344a818bRoboErik synchronized (mLock) { 1529563acea6665c45902bbc46db1a22c036344a818bRoboErik vp = mVolumeProvider; 1530563acea6665c45902bbc46db1a22c036344a818bRoboErik } 1531563acea6665c45902bbc46db1a22c036344a818bRoboErik if (vp != null) { 153221c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim vp.onAdjustVolume((int) obj); 1533563acea6665c45902bbc46db1a22c036344a818bRoboErik } 1534563acea6665c45902bbc46db1a22c036344a818bRoboErik break; 1535563acea6665c45902bbc46db1a22c036344a818bRoboErik case MSG_SET_VOLUME: 1536563acea6665c45902bbc46db1a22c036344a818bRoboErik synchronized (mLock) { 1537563acea6665c45902bbc46db1a22c036344a818bRoboErik vp = mVolumeProvider; 1538563acea6665c45902bbc46db1a22c036344a818bRoboErik } 1539563acea6665c45902bbc46db1a22c036344a818bRoboErik if (vp != null) { 154021c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim vp.onSetVolumeTo((int) obj); 1541563acea6665c45902bbc46db1a22c036344a818bRoboErik } 1542563acea6665c45902bbc46db1a22c036344a818bRoboErik break; 154374d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: 154474d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim mCallback.handleMediaPlayPauseKeySingleTapIfPending(); 154574d002be26ec9800cb494471f0773493bc83d8f7Jaewan Kim break; 1546c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 154721c23e30b434ba23aa489f89f94a32b77c46e35aJaewan Kim mCurrentControllerInfo = null; 1548c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 1549c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik } 155001fe661ae5da3739215d93922412df4b24c859a2RoboErik} 1551