124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/* 224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Copyright (C) 2014 The Android Open Source Project 324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * you may not use this file except in compliance with the License. 624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * You may obtain a copy of the License at 724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 1024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Unless required by applicable law or agreed to in writing, software 1124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * See the License for the specific language governing permissions and 1424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * limitations under the License. 1524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 1624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 1724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpackage android.support.v4.media.session; 1824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 19aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport android.app.PendingIntent; 2024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.content.Context; 21aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport android.media.AudioManager; 22aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport android.net.Uri; 2324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Bundle; 2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Handler; 25e49860b0f76d8336c1d41831ed370b0ff94278efRoboErikimport android.os.IBinder; 26e49860b0f76d8336c1d41831ed370b0ff94278efRoboErikimport android.os.Looper; 27e49860b0f76d8336c1d41831ed370b0ff94278efRoboErikimport android.os.Message; 2824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.RemoteException; 2924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.ResultReceiver; 3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.MediaMetadataCompat; 3124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.RatingCompat; 3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.VolumeProviderCompat; 33e49860b0f76d8336c1d41831ed370b0ff94278efRoboErikimport android.support.v4.media.session.MediaSessionCompat.QueueItem; 34aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport android.support.v4.media.session.PlaybackStateCompat.CustomAction; 3524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.text.TextUtils; 36e49860b0f76d8336c1d41831ed370b0ff94278efRoboErikimport android.util.Log; 3724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.view.KeyEvent; 3824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 39aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport java.util.ArrayList; 40aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport java.util.List; 41aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 4224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/** 4324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Allows an app to interact with an ongoing media session. Media buttons and 4424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * other commands can be sent to the session. A callback may be registered to 4524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * receive updates from the session, such as metadata and play state changes. 4624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 4724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * A MediaController can be created if you have a {@link MediaSessionCompat.Token} 4824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * from the session owner. 4924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 5024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * MediaController objects are thread-safe. 5124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 5224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * This is a helper for accessing features in {@link android.media.session.MediaSession} 5324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * introduced after API level 4 in a backwards compatible fashion. 5424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpublic final class MediaControllerCompat { 56e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final String TAG = "MediaControllerCompat"; 57e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 5824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final MediaControllerImpl mImpl; 5994be6100218126ce6a08bf1f56209578500b361fRoboErik private final MediaSessionCompat.Token mToken; 6024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Creates a media controller from a session. 6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param session The session to be controlled. 6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerCompat(Context context, MediaSessionCompat session) { 6724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (session == null) { 6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("session must not be null"); 6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7094be6100218126ce6a08bf1f56209578500b361fRoboErik mToken = session.getSessionToken(); 7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 72b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake if (android.os.Build.VERSION.SDK_INT >= 23) { 73b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake mImpl = new MediaControllerImplApi23(context, session); 74b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } else if (android.os.Build.VERSION.SDK_INT >= 21) { 7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, session); 7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 77e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mImpl = new MediaControllerImplBase(mToken); 7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Creates a media controller from a session token which may have 8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * been obtained from another process. 8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param sessionToken The token of the session to be controlled. 8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @throws RemoteException if the session is not accessible. 8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerCompat(Context context, MediaSessionCompat.Token sessionToken) 8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (sessionToken == null) { 9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("sessionToken must not be null"); 9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9394be6100218126ce6a08bf1f56209578500b361fRoboErik mToken = sessionToken; 9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, sessionToken); 9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 98e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mImpl = new MediaControllerImplBase(mToken); 9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get a {@link TransportControls} instance for this session. 10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return A controls instance 10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getTransportControls(); 10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Send the specified media button event to the session. Only media keys can 11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * be sent by this method, other keys will be ignored. 11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param keyEvent The media button event to dispatch. 11624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return true if the event was sent to the session, false otherwise. 11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { 11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (keyEvent == null) { 12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("KeyEvent may not be null"); 12124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.dispatchMediaButtonEvent(keyEvent); 12324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 12624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current playback state for this session. 12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current PlaybackState or null 12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getPlaybackState(); 13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current metadata for this session. 13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current MediaMetadata or null. 13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMetadata(); 14124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 14224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 14324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 144aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the current play queue for this session if one is set. If you only 145aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * care about the current item {@link #getMetadata()} should be used. 146aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 147aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The current play queue or null. 148aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 149aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 150aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getQueue(); 151aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 152aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 153aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 154aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the queue title for this session. 155aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 156aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 157aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getQueueTitle(); 158aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 159aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 160aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 161aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the extras for this session. 162aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 163aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 164aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getExtras(); 165aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 166aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 167aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the rating type supported by the session. One of: 16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_NONE}</li> 17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_HEART}</li> 17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_THUMB_UP_DOWN}</li> 17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_3_STARS}</li> 17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_4_STARS}</li> 17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_5_STARS}</li> 17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_PERCENTAGE}</li> 17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The supported rating type 18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getRatingType(); 18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 186aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the flags for this session. Flags are defined in 187aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat}. 188aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 189aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The current set of flags for the session. 190aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 191aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 192aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getFlags(); 193aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 194aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 195aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 196312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * Get the current playback info for this session. 19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 198312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * @return The current playback info or null. 19924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 200312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 201312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return mImpl.getPlaybackInfo(); 20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 20324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 20424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 205aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get an intent for launching UI associated with this session if one 206aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * exists. 207aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 208aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return A {@link PendingIntent} to launch UI or null. 209aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 210aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 211aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getSessionActivity(); 212aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 213aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 214aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 21594be6100218126ce6a08bf1f56209578500b361fRoboErik * Get the token for the session this controller is connected to. 21694be6100218126ce6a08bf1f56209578500b361fRoboErik * 21794be6100218126ce6a08bf1f56209578500b361fRoboErik * @return The session's token. 21894be6100218126ce6a08bf1f56209578500b361fRoboErik */ 21994be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getSessionToken() { 22094be6100218126ce6a08bf1f56209578500b361fRoboErik return mToken; 22194be6100218126ce6a08bf1f56209578500b361fRoboErik } 22294be6100218126ce6a08bf1f56209578500b361fRoboErik 22394be6100218126ce6a08bf1f56209578500b361fRoboErik /** 224aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Set the volume of the output this session is playing on. The command will 225aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * be ignored if it does not support 226aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}. The flags in 227aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager} may be used to affect the handling. 228aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 229aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #getPlaybackInfo() 230aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param value The value to set it to, between 0 and the reported max. 231aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param flags Flags from {@link AudioManager} to include with the volume 232aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * request. 233aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 234aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 235aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik mImpl.setVolumeTo(value, flags); 236aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 237aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 238aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 239aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Adjust the volume of the output this session is playing on. The direction 240aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * must be one of {@link AudioManager#ADJUST_LOWER}, 241aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}. 242aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * The command will be ignored if the session does not support 243aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE} or 244aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}. The flags in 245aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager} may be used to affect the handling. 246aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 247aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #getPlaybackInfo() 248aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param direction The direction to adjust the volume in. 249aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param flags Any flags to pass with the command. 250aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 251aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 252aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik mImpl.adjustVolume(direction, flags); 253aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 254aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 255aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the Session. Updates will be 25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the caller's thread. 25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 25924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 26024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 26116ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback) { 26216ac83bebda2a19930b9d692789f3b507c49951bRoboErik registerCallback(callback, null); 26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 26524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 26624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the session. Updates will be 26724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the specified handler's thread. 26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param handler The handler to post updates on. If null the callers thread 27124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * will be used. 27224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 27316ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 27424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 27724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (handler == null) { 27824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown handler = new Handler(); 27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28016ac83bebda2a19930b9d692789f3b507c49951bRoboErik mImpl.registerCallback(callback, handler); 28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 28324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 28424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Stop receiving updates on the specified callback. If an update has 28524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * already been posted you may still receive it after calling this method. 28624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 28724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback to remove 28824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 28916ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 29024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 29124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 29224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29316ac83bebda2a19930b9d692789f3b507c49951bRoboErik mImpl.unregisterCallback(callback); 29424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 29724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Sends a generic command to the session. It is up to the session creator 29824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to decide what commands and parameters they will support. As such, 29924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * commands should only be sent to sessions that the controller owns. 30024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 30124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param command The command to send 30224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param params Any parameters to include with the command 30324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param cb The callback to receive the result on 30424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 305b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 30624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (TextUtils.isEmpty(command)) { 30724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("command cannot be null or empty"); 30824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 309b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal mImpl.sendCommand(command, params, cb); 31024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 31124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 31224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 313aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the session owner's package name. 314aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 315aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The package name of of the session owner. 316aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 317aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 318aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getPackageName(); 319aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 320aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 321aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 322aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Gets the underlying framework 323aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link android.media.session.MediaController} object. 32424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 32524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * This method is only supported on API 21+. 32624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </p> 32724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 328aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The underlying {@link android.media.session.MediaController} 329aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * object, or null if none. 33024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 33124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 33224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMediaController(); 33324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 33424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 33524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 33624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Callback for receiving updates on from the session. A Callback can be 33716ac83bebda2a19930b9d692789f3b507c49951bRoboErik * registered using {@link #registerCallback} 33824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 339e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public static abstract class Callback implements IBinder.DeathRecipient { 340e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private final Object mCallbackObj; 341e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private MessageHandler mHandler; 342e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 343e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mRegistered = false; 34424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 34524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Callback() { 34624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 34724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21()); 34824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 349e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mCallbackObj = new StubCompat(); 35024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 35124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 35224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 35324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 35423138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik * Override to handle the session being destroyed. The session is no 35523138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik * longer valid after this call and calls to it will be ignored. 35623138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik */ 35723138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik public void onSessionDestroyed() { 35823138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik } 35923138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik 36023138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik /** 36124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle custom events sent by the session owner without a 36224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * specified interface. Controllers should only handle these for 36324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * sessions they own. 36424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 36524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param event The event from the session. 36624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param extras Optional parameters for the event. 36724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 36824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 36924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 37124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 37224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes in playback state. 37324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 37424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param state The new playback state of the session 37524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 37624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(PlaybackStateCompat state) { 37724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 37924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 38024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes to the current metadata. 38124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 38224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param metadata The current metadata for the session or null if none. 38324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @see MediaMetadata 38424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 38524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(MediaMetadataCompat metadata) { 38624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 38724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 388aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 389aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to items in the queue. 390aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 391aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see MediaSessionCompat.QueueItem 392aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param queue A list of items in the current play queue. It should 393aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * include the currently playing item as well as previous and 394aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * upcoming items if applicable. 395aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 396aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) { 397aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 398aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 399aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 400aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to the queue title. 401aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 402aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param title The title that should be displayed along with the play 403aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * queue such as "Now Playing". May be null if there is no 404aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * such title. 405aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 406aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onQueueTitleChanged(CharSequence title) { 407aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 408aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 409aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 410aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle chagnes to the {@link MediaSessionCompat} extras. 411aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 412aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras The extras that can include other information 413aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * associated with the {@link MediaSessionCompat}. 414aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 415aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onExtrasChanged(Bundle extras) { 416aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 417aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 418aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 419aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to the audio info. 420aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 421aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param info The current audio info for this session. 422aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 423aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onAudioInfoChanged(PlaybackInfo info) { 424aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 425aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 426e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 427e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void binderDied() { 428e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionDestroyed(); 429e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 430e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 431e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik /** 432e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik * Set the handler to use for pre 21 callbacks. 433e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik */ 434e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setHandler(Handler handler) { 435e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler = new MessageHandler(handler.getLooper()); 436e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 437e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 43824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private class StubApi21 implements MediaControllerCompatApi21.Callback { 43924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 44023138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik public void onSessionDestroyed() { 44123138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik Callback.this.onSessionDestroyed(); 44223138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik } 44323138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik 44423138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik @Override 44524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 44624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onSessionEvent(event, extras); 44724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 44924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 45024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(Object stateObj) { 45124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onPlaybackStateChanged( 45224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat.fromPlaybackState(stateObj)); 45324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 45424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 45524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 45624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(Object metadataObj) { 45724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onMetadataChanged( 45824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat.fromMediaMetadata(metadataObj)); 45924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 46024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 461e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 462e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private class StubCompat extends IMediaControllerCallback.Stub { 463e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 464e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 465e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onEvent(String event, Bundle extras) throws RemoteException { 466e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_EVENT, event, extras); 467e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 468e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 469e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 470e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onSessionDestroyed() throws RemoteException { 471e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_DESTROYED, null, null); 472e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 473e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 474e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 475e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) throws RemoteException { 476e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE, state, null); 477e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 478e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 479e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 480e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) throws RemoteException { 481e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_METADATA, metadata, null); 482e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 483e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 484e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 485e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onQueueChanged(List<QueueItem> queue) throws RemoteException { 486e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_QUEUE, queue, null); 487e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 488e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 489e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 490e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onQueueTitleChanged(CharSequence title) throws RemoteException { 491e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_QUEUE_TITLE, title, null); 492e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 493e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 494e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 495e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onExtrasChanged(Bundle extras) throws RemoteException { 496e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS, extras, null); 497e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 498e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 499e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 500e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException { 501e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik PlaybackInfo pi = null; 502e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (info != null) { 503e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik pi = new PlaybackInfo(info.volumeType, info.audioStream, info.controlType, 504e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik info.maxVolume, info.currentVolume); 505e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 506e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_VOLUME, pi, null); 507e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 508e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 509e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 510e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private class MessageHandler extends Handler { 511e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_EVENT = 1; 512e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_PLAYBACK_STATE = 2; 513e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_METADATA = 3; 514e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_VOLUME = 4; 515e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_QUEUE = 5; 516e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_QUEUE_TITLE = 6; 517e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_EXTRAS = 7; 518e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_DESTROYED = 8; 519e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 520e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public MessageHandler(Looper looper) { 521e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik super(looper); 522e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 523e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 524e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 525e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void handleMessage(Message msg) { 526e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mRegistered) { 527e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 528e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 529e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik switch (msg.what) { 530e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_EVENT: 531e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionEvent((String) msg.obj, msg.getData()); 532e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 533e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_PLAYBACK_STATE: 534e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onPlaybackStateChanged((PlaybackStateCompat) msg.obj); 535e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 536e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_METADATA: 537e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onMetadataChanged((MediaMetadataCompat) msg.obj); 538e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 539e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_QUEUE: 540e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onQueueChanged((List<MediaSessionCompat.QueueItem>) msg.obj); 541e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 542e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_QUEUE_TITLE: 543e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onQueueTitleChanged((CharSequence) msg.obj); 544e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 545e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_EXTRAS: 546e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onExtrasChanged((Bundle) msg.obj); 547e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 548e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_VOLUME: 549e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onAudioInfoChanged((PlaybackInfo) msg.obj); 550e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 551e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_DESTROYED: 552e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionDestroyed(); 553e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 554e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 555e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 556e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 557e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void post(int what, Object obj, Bundle data) { 558e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik obtainMessage(what, obj).sendToTarget(); 559e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 560e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 56124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 56224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 56324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 56424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Interface for controlling media playback on a session. This allows an app 56524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to send media transport commands to the session. 56624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 56724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static abstract class TransportControls { 56824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls() { 56924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 57024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 57124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 57224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player start its playback at its current position. 57324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 57424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void play(); 57524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 57624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 577aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Request that the player start playback for a specific {@link Uri}. 578aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 579aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param mediaId The uri of the requested media. 580aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras Optional extras that can include extra information 581aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * about the media item to be played. 582aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 583aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void playFromMediaId(String mediaId, Bundle extras); 584aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 585aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 586aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Request that the player start playback for a specific search query. 587aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * An empty or null query should be treated as a request to play any 588aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * music. 589aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 590aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param query The search query. 591aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras Optional extras that can include extra information 592aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * about the query. 593aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 594aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void playFromSearch(String query, Bundle extras); 595aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 596aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 597b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * Request that the player start playback for a specific {@link Uri}. 598229e04bbc3590e8371b5f4b0d46300adaea7f1d5Dongwon Kang * <p> 599229e04bbc3590e8371b5f4b0d46300adaea7f1d5Dongwon Kang * This method is not supported on API 21-22. 600229e04bbc3590e8371b5f4b0d46300adaea7f1d5Dongwon Kang * </p> 601b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * 602b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * @param uri The URI of the requested media. 603b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * @param extras Optional extras that can include extra information about the media item 604b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * to be played. 605b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake */ 606b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public abstract void playFromUri(Uri uri, Bundle extras); 607b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 608b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake /** 609aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Play an item with a specific id in the play queue. If you specify an 610aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * id that is not in the play queue, the behavior is undefined. 611aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 612aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void skipToQueueItem(long id); 613aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 614aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 61524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player pause its playback and stay at its current 61624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * position. 61724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 61824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void pause(); 61924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 62024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 62124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player stop its playback; it may clear its state in 62224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * whatever way is appropriate. 62324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 62424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void stop(); 62524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 62624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 62724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Move to a new location in the media stream. 62824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 62924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param pos Position to move to, in milliseconds. 63024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void seekTo(long pos); 63224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 63424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start fast forwarding. If playback is already fast forwarding this 63524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * may increase the rate. 63624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void fastForward(); 63824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 64024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the next item. 64124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 64224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToNext(); 64324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 64424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 64524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start rewinding. If playback is already rewinding this may increase 64624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the rate. 64724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 64824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void rewind(); 64924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 65024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 65124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the previous item. 65224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 65324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToPrevious(); 65424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 65524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 65624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Rate the current content. This will cause the rating to be set for 65724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the current user. The Rating type must match the type returned by 65824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * {@link #getRatingType()}. 65924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 66024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param rating The rating to set for the current content 66124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 66224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void setRating(RatingCompat rating); 663aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 664aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 665aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send a custom action for the {@link MediaSessionCompat} to perform. 666aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 667aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param customAction The action to perform. 668aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 669aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 670aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 671aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(PlaybackStateCompat.CustomAction customAction, 672aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle args); 673aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 674aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 675aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send the id and args from a custom action for the 676aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} to perform. 677aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 678aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #sendCustomAction(PlaybackStateCompat.CustomAction action, 679aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Bundle args) 680aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param action The action identifier of the 681aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link PlaybackStateCompat.CustomAction} as specified by 682aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * the {@link MediaSessionCompat}. 683aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 684aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 685aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 686aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(String action, Bundle args); 68724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 68824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 68924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 69024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Holds information about the way volume is handled for this session. 69124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 692312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final class PlaybackInfo { 693312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 694312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses local playback. 695312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 696312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_LOCAL = 1; 697312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 698312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses remote playback. 699312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 700312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_REMOTE = 2; 701312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik 702312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik private final int mPlaybackType; 7031435afe32073dee10e721dfb6122ce6a194a6412RoboErik // TODO update audio stream with AudioAttributes support version 70424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mAudioStream; 70524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mVolumeControl; 70624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mMaxVolume; 70724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mCurrentVolume; 70824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 709312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo(int type, int stream, int control, int max, int current) { 710312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik mPlaybackType = type; 71124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mAudioStream = stream; 71224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mVolumeControl = control; 71324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mMaxVolume = max; 71424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCurrentVolume = current; 71524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 71624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 71724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 71824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume handling, either local or remote. One of: 71924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 720312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_LOCAL}</li> 721312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_REMOTE}</li> 72224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 72324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 72424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume handling this session is using. 72524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 726312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public int getPlaybackType() { 727312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return mPlaybackType; 72824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 72924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 73024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 73124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the stream this is currently controlling volume on. When the volume 732312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * type is {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} this value does not 73324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * have meaning and should be ignored. 73424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 73524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The stream this session is playing on. 73624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 73724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getAudioStream() { 738aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik // TODO switch to AudioAttributesCompat when it is added. 73924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mAudioStream; 74024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 74124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 74224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 74324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume control that can be used. One of: 74424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 74524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}</li> 74624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE}</li> 74724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_FIXED}</li> 74824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 74924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 75024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume control that may be used with this 75124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * session. 75224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 75324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getVolumeControl() { 75424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mVolumeControl; 75524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 75624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 75724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 75824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the maximum volume that may be set for this session. 75924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 76024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The maximum allowed volume where this session is playing. 76124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 76224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getMaxVolume() { 76324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mMaxVolume; 76424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 76524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 76624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 76724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current volume for this session. 76824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 76924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current volume where this session is playing. 77024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 77124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getCurrentVolume() { 77224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mCurrentVolume; 77324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 77424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 77524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 77624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown interface MediaControllerImpl { 77716ac83bebda2a19930b9d692789f3b507c49951bRoboErik void registerCallback(Callback callback, Handler handler); 77816ac83bebda2a19930b9d692789f3b507c49951bRoboErik 77916ac83bebda2a19930b9d692789f3b507c49951bRoboErik void unregisterCallback(Callback callback); 78024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown boolean dispatchMediaButtonEvent(KeyEvent keyEvent); 78124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls getTransportControls(); 78224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat getPlaybackState(); 78324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat getMetadata(); 784aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 785aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> getQueue(); 786aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik CharSequence getQueueTitle(); 787aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle getExtras(); 78824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int getRatingType(); 789aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik long getFlags(); 790312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo getPlaybackInfo(); 791aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik PendingIntent getSessionActivity(); 792aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 793aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void setVolumeTo(int value, int flags); 794aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void adjustVolume(int direction, int flags); 795b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal void sendCommand(String command, Bundle params, ResultReceiver cb); 796aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 797aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik String getPackageName(); 79824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object getMediaController(); 79924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 80024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 80124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplBase implements MediaControllerImpl { 802e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private MediaSessionCompat.Token mToken; 803e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 804e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private TransportControls mTransportControls; 805e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 806e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public MediaControllerImplBase(MediaSessionCompat.Token token) { 807e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mToken = token; 808e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken()); 809e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 810e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 81124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 81216ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 813e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 814e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 815e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 816e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 817e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().linkToDeath(callback, 0); 818e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.registerCallbackListener((IMediaControllerCallback) callback.mCallbackObj); 819e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.setHandler(handler); 820e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = true; 821e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 822e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in registerCallback. " + e); 823e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.onSessionDestroyed(); 824e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 82524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 82624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 82724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 82816ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 829e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 830e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 831e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 832e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 833e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.unregisterCallbackListener( 834e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik (IMediaControllerCallback) callback.mCallbackObj); 835e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().unlinkToDeath(callback, 0); 836e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = false; 837e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 838e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in unregisterCallback. " + e); 839e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 84024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 84124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 84224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 84324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 844e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (event == null) { 845e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("event may not be null."); 846e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 847e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 848e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendMediaButton(event); 849e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 850e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in dispatchMediaButtonEvent. " + e); 851e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 85224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return false; 85324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 85424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 85524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 85624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 857e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (mTransportControls == null) { 858e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mTransportControls = new TransportControlsBase(mBinder); 859e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 860e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 861e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mTransportControls; 86224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 86324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 86424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 86524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 866e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 867e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPlaybackState(); 868e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 869e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackState. " + e); 870e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 87124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 87224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 87324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 87424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 87524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 876e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 877e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getMetadata(); 878e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 879e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getMetadata. " + e); 880e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 88124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 88224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 88324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 88424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 885aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 886e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 887e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueue(); 888e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 889e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueue. " + e); 890e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 891aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 892aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 893aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 894aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 895aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 896e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 897e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueueTitle(); 898e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 899e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueueTitle. " + e); 900e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 901aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 902aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 903aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 904aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 905aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 906e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 907e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getExtras(); 908e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 909e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getExtras. " + e); 910e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 911aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 912aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 913aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 914aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 91524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 916e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 917e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getRatingType(); 918e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 919e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getRatingType. " + e); 920e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 92124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return 0; 92224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 92324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 92424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 925aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 926e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 927e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getFlags(); 928e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 929e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getFlags. " + e); 930e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 931aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return 0; 932aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 933aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 934aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 935312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 936e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 937e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik ParcelableVolumeInfo info = mBinder.getVolumeAttributes(); 938e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik PlaybackInfo pi = new PlaybackInfo(info.volumeType, info.audioStream, 939e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik info.controlType, info.maxVolume, info.currentVolume); 940e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return pi; 941e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 942e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackInfo. " + e); 943e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 94424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 94524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 94624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 94724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 948aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 949e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 950e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getLaunchPendingIntent(); 951e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 952e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getSessionActivity. " + e); 953e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 954aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 955aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 956aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 957aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 958aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 959e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 960e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.setVolumeTo(value, flags, null); 961e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 962e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setVolumeTo. " + e); 963e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 964aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 965aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 966aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 967aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 968e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 969e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.adjustVolume(direction, flags, null); 970e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 971e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in adjustVolume. " + e); 972e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 973aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 974aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 975aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 976b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 977e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 978e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCommand(command, params, 979e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik new MediaSessionCompat.ResultReceiverWrapper(cb)); 980e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 981e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCommand. " + e); 982e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 98324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 98424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 98524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 986aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 987e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 988e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPackageName(); 989e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 990e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPackageName. " + e); 991e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 992aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 993aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 994aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 995aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 99624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 99724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 99824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 99924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 100024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 1001e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik static class TransportControlsBase extends TransportControls { 1002e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 1003e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1004e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public TransportControlsBase(IMediaSession binder) { 1005e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = binder; 1006e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1007e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1008e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1009e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void play() { 1010e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1011e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.play(); 1012e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1013e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in play. " + e); 1014e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1015e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1016e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1017e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1018e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1019e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1020e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromMediaId(mediaId, extras); 1021e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1022e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromMediaId. " + e); 1023e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1024e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1025e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1026e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1027e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromSearch(String query, Bundle extras) { 1028e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1029e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromSearch(query, extras); 1030e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1031e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromSearch. " + e); 1032e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1033e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1034e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1035e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1036b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1037b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake try { 1038b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake mBinder.playFromUri(uri, extras); 1039b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } catch (RemoteException e) { 1040b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake Log.e(TAG, "Dead object in playFromUri. " + e); 1041b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1042b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1043b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1044b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1045e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToQueueItem(long id) { 1046e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1047e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.skipToQueueItem(id); 1048e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1049e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToQueueItem. " + e); 1050e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1051e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1052e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1053e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1054e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void pause() { 1055e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1056e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.pause(); 1057e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1058e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in pause. " + e); 1059e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1060e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1061e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1062e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1063e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void stop() { 1064e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1065e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.stop(); 1066e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1067e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in stop. " + e); 1068e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1069e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1070e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1071e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1072e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void seekTo(long pos) { 1073e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1074e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.seekTo(pos); 1075e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1076e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in seekTo. " + e); 1077e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1078e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1079e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1080e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1081e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void fastForward() { 1082e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1083e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.fastForward(); 1084e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1085e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in fastForward. " + e); 1086e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1087e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1088e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1089e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1090e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToNext() { 1091e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1092e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.next(); 1093e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1094e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToNext. " + e); 1095e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1096e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1097e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1098e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1099e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void rewind() { 1100e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1101e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rewind(); 1102e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1103e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in rewind. " + e); 1104e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1105e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1106e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1107e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1108e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToPrevious() { 1109e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1110e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.previous(); 1111e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1112e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToPrevious. " + e); 1113e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1114e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1115e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1116e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1117e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void setRating(RatingCompat rating) { 1118e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1119e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rate(rating); 1120e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1121e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setRating. " + e); 1122e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1123e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1124e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1125e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1126e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1127e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik sendCustomAction(customAction.getAction(), args); 1128e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1129e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1130e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1131e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(String action, Bundle args) { 1132e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1133e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCustomAction(action, args); 1134e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1135e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCustomAction. " + e); 1136e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1137e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1138e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1139e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 114024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplApi21 implements MediaControllerImpl { 1141b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake protected final Object mControllerObj; 114224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat session) { 11445c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 114524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown session.getSessionToken().getToken()); 114624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 114724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken) 114924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 11505c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 115124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown sessionToken.getToken()); 115224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mControllerObj == null) throw new RemoteException(); 115324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 115524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 115616ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 115716ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.registerCallback(mControllerObj, callback.mCallbackObj, handler); 115824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 116024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 116116ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 116216ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.unregisterCallback(mControllerObj, callback.mCallbackObj); 116324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 116424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 116524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 116624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 116724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.dispatchMediaButtonEvent(mControllerObj, event); 116824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 116924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 117024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 117124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 11721435afe32073dee10e721dfb6122ce6a194a6412RoboErik Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 117324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return controlsObj != null ? new TransportControlsApi21(controlsObj) : null; 117424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 117524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 117624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 117724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 117824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object stateObj = MediaControllerCompatApi21.getPlaybackState(mControllerObj); 117924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return stateObj != null ? PlaybackStateCompat.fromPlaybackState(stateObj) : null; 118024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 118124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 118224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 118324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 118424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object metadataObj = MediaControllerCompatApi21.getMetadata(mControllerObj); 118524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return metadataObj != null ? MediaMetadataCompat.fromMediaMetadata(metadataObj) : null; 118624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 118724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 118824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1189aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 1190aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<Object> queueObjs = MediaControllerCompatApi21.getQueue(mControllerObj); 1191aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik if (queueObjs == null) { 1192aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 1193aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1194aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> queue = 1195aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik new ArrayList<MediaSessionCompat.QueueItem>(); 1196aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik for (Object item : queueObjs) { 1197aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik queue.add(MediaSessionCompat.QueueItem.obtain(item)); 1198aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1199aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return queue; 1200aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1201aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1202aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1203aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 1204aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getQueueTitle(mControllerObj); 1205aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1206aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1207aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1208aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 1209aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getExtras(mControllerObj); 1210aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1211aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1212aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 121324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 121424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.getRatingType(mControllerObj); 121524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 121624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 121724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1218aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 1219aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getFlags(mControllerObj); 1220aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1221aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1222aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1223312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 1224312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik Object volumeInfoObj = MediaControllerCompatApi21.getPlaybackInfo(mControllerObj); 1225312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return volumeInfoObj != null ? new PlaybackInfo( 1226312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getPlaybackType(volumeInfoObj), 1227312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getLegacyAudioStream(volumeInfoObj), 1228312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getVolumeControl(volumeInfoObj), 1229312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getMaxVolume(volumeInfoObj), 1230312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getCurrentVolume(volumeInfoObj)) : null; 123124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 123224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 123324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1234aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 1235aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getSessionActivity(mControllerObj); 1236aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1237aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1238aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1239aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 1240aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.setVolumeTo(mControllerObj, value, flags); 1241aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1242aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1243aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1244aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 1245aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.adjustVolume(mControllerObj, direction, flags); 1246aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1247aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1248aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1249b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 1250b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal MediaControllerCompatApi21.sendCommand(mControllerObj, command, params, cb); 125124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 125224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 125324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1254aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 1255aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getPackageName(mControllerObj); 1256aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1257aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1258aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 125924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 126024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mControllerObj; 126124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class TransportControlsApi21 extends TransportControls { 1265b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake protected final Object mControlsObj; 126624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControlsApi21(Object controlsObj) { 126824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mControlsObj = controlsObj; 126924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void play() { 127324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.play(mControlsObj); 127424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void pause() { 127824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.pause(mControlsObj); 127924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void stop() { 128324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.stop(mControlsObj); 128424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void seekTo(long pos) { 128824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.seekTo(mControlsObj, pos); 128924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 129024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 129124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 129224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void fastForward() { 129324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.fastForward(mControlsObj); 129424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 129524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 129624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 129724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void rewind() { 129824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.rewind(mControlsObj); 129924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 130024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 130124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 130224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToNext() { 130324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToNext(mControlsObj); 130424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 130524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 130624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 130724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToPrevious() { 130824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToPrevious(mControlsObj); 130924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 131024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 131124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 131224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void setRating(RatingCompat rating) { 131324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.setRating(mControlsObj, 131424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown rating != null ? rating.getRating() : null); 131524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 1316aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1317aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1318aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1319aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromMediaId(mControlsObj, mediaId, 1320aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1321aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1322aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1323aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1324aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromSearch(String query, Bundle extras) { 1325aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromSearch(mControlsObj, query, 1326aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1327aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1328aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1329aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1330b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1331b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1332b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1333b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1334aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void skipToQueueItem(long id) { 1335aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.skipToQueueItem(mControlsObj, id); 1336aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1337aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1338aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1339aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1340aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, 1341aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik customAction.getAction(), args); 1342aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1343aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1344aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1345aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(String action, Bundle args) { 1346aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, action, 1347aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik args); 1348aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 134924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 1350b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1351b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake static class MediaControllerImplApi23 extends MediaControllerImplApi21 { 1352b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1353b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public MediaControllerImplApi23(Context context, MediaSessionCompat session) { 1354b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(context, session); 1355b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1356b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1357b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public MediaControllerImplApi23(Context context, MediaSessionCompat.Token sessionToken) 1358b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake throws RemoteException { 1359b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(context, sessionToken); 1360b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1361b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1362b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1363b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public TransportControls getTransportControls() { 1364b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 1365b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake return controlsObj != null ? new TransportControlsApi23(controlsObj) : null; 1366b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1367b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1368b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1369b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake static class TransportControlsApi23 extends TransportControlsApi21 { 1370b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1371b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public TransportControlsApi23(Object controlsObj) { 1372b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(controlsObj); 1373b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1374b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1375b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1376b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1377b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake MediaControllerCompatApi23.TransportControls.playFromUri(mControlsObj, uri, 1378b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake extras); 1379b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1380b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 138124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 1382