MediaControllerCompat.java revision b51f456b92aeb62d5aa9d67e1fb2725b2035fddd
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}. 598b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * 599b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * @param uri The URI of the requested media. 600b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * @param extras Optional extras that can include extra information about the media item 601b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake * to be played. 602b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake */ 603b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public abstract void playFromUri(Uri uri, Bundle extras); 604b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 605b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake /** 606aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Play an item with a specific id in the play queue. If you specify an 607aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * id that is not in the play queue, the behavior is undefined. 608aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 609aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void skipToQueueItem(long id); 610aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 611aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 61224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player pause its playback and stay at its current 61324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * position. 61424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 61524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void pause(); 61624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 61724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 61824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player stop its playback; it may clear its state in 61924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * whatever way is appropriate. 62024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 62124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void stop(); 62224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 62324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 62424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Move to a new location in the media stream. 62524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 62624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param pos Position to move to, in milliseconds. 62724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 62824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void seekTo(long pos); 62924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 63124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start fast forwarding. If playback is already fast forwarding this 63224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * may increase the rate. 63324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void fastForward(); 63524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 63724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the next item. 63824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToNext(); 64024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 64124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 64224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start rewinding. If playback is already rewinding this may increase 64324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the rate. 64424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 64524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void rewind(); 64624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 64724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 64824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the previous item. 64924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 65024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToPrevious(); 65124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 65224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 65324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Rate the current content. This will cause the rating to be set for 65424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the current user. The Rating type must match the type returned by 65524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * {@link #getRatingType()}. 65624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 65724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param rating The rating to set for the current content 65824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 65924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void setRating(RatingCompat rating); 660aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 661aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 662aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send a custom action for the {@link MediaSessionCompat} to perform. 663aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 664aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param customAction The action to perform. 665aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 666aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 667aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 668aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(PlaybackStateCompat.CustomAction customAction, 669aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle args); 670aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 671aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 672aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send the id and args from a custom action for the 673aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} to perform. 674aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 675aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #sendCustomAction(PlaybackStateCompat.CustomAction action, 676aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Bundle args) 677aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param action The action identifier of the 678aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link PlaybackStateCompat.CustomAction} as specified by 679aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * the {@link MediaSessionCompat}. 680aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 681aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 682aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 683aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(String action, Bundle args); 68424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 68524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 68624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 68724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Holds information about the way volume is handled for this session. 68824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 689312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final class PlaybackInfo { 690312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 691312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses local playback. 692312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 693312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_LOCAL = 1; 694312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 695312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses remote playback. 696312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 697312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_REMOTE = 2; 698312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik 699312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik private final int mPlaybackType; 7001435afe32073dee10e721dfb6122ce6a194a6412RoboErik // TODO update audio stream with AudioAttributes support version 70124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mAudioStream; 70224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mVolumeControl; 70324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mMaxVolume; 70424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mCurrentVolume; 70524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 706312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo(int type, int stream, int control, int max, int current) { 707312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik mPlaybackType = type; 70824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mAudioStream = stream; 70924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mVolumeControl = control; 71024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mMaxVolume = max; 71124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCurrentVolume = current; 71224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 71324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 71424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 71524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume handling, either local or remote. One of: 71624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 717312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_LOCAL}</li> 718312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_REMOTE}</li> 71924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 72024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 72124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume handling this session is using. 72224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 723312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public int getPlaybackType() { 724312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return mPlaybackType; 72524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 72624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 72724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 72824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the stream this is currently controlling volume on. When the volume 729312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * type is {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} this value does not 73024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * have meaning and should be ignored. 73124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 73224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The stream this session is playing on. 73324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 73424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getAudioStream() { 735aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik // TODO switch to AudioAttributesCompat when it is added. 73624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mAudioStream; 73724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 73824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 73924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 74024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume control that can be used. One of: 74124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 74224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}</li> 74324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE}</li> 74424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_FIXED}</li> 74524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 74624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 74724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume control that may be used with this 74824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * session. 74924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 75024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getVolumeControl() { 75124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mVolumeControl; 75224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 75324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 75424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 75524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the maximum volume that may be set for this session. 75624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 75724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The maximum allowed volume where this session is playing. 75824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 75924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getMaxVolume() { 76024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mMaxVolume; 76124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 76224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 76324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 76424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current volume for this session. 76524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 76624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current volume where this session is playing. 76724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 76824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getCurrentVolume() { 76924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mCurrentVolume; 77024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 77124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 77224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 77324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown interface MediaControllerImpl { 77416ac83bebda2a19930b9d692789f3b507c49951bRoboErik void registerCallback(Callback callback, Handler handler); 77516ac83bebda2a19930b9d692789f3b507c49951bRoboErik 77616ac83bebda2a19930b9d692789f3b507c49951bRoboErik void unregisterCallback(Callback callback); 77724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown boolean dispatchMediaButtonEvent(KeyEvent keyEvent); 77824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls getTransportControls(); 77924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat getPlaybackState(); 78024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat getMetadata(); 781aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 782aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> getQueue(); 783aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik CharSequence getQueueTitle(); 784aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle getExtras(); 78524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int getRatingType(); 786aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik long getFlags(); 787312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo getPlaybackInfo(); 788aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik PendingIntent getSessionActivity(); 789aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 790aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void setVolumeTo(int value, int flags); 791aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void adjustVolume(int direction, int flags); 792b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal void sendCommand(String command, Bundle params, ResultReceiver cb); 793aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 794aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik String getPackageName(); 79524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object getMediaController(); 79624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 79724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 79824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplBase implements MediaControllerImpl { 799e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private MediaSessionCompat.Token mToken; 800e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 801e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private TransportControls mTransportControls; 802e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 803e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public MediaControllerImplBase(MediaSessionCompat.Token token) { 804e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mToken = token; 805e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken()); 806e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 807e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 80824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 80916ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 810e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 811e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 812e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 813e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 814e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().linkToDeath(callback, 0); 815e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.registerCallbackListener((IMediaControllerCallback) callback.mCallbackObj); 816e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.setHandler(handler); 817e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = true; 818e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 819e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in registerCallback. " + e); 820e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.onSessionDestroyed(); 821e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 82224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 82324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 82424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 82516ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 826e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 827e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 828e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 829e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 830e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.unregisterCallbackListener( 831e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik (IMediaControllerCallback) callback.mCallbackObj); 832e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().unlinkToDeath(callback, 0); 833e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = false; 834e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 835e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in unregisterCallback. " + e); 836e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 83724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 83824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 83924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 84024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 841e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (event == null) { 842e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("event may not be null."); 843e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 844e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 845e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendMediaButton(event); 846e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 847e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in dispatchMediaButtonEvent. " + e); 848e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 84924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return false; 85024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 85124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 85224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 85324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 854e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (mTransportControls == null) { 855e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mTransportControls = new TransportControlsBase(mBinder); 856e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 857e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 858e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mTransportControls; 85924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 86024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 86124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 86224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 863e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 864e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPlaybackState(); 865e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 866e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackState. " + e); 867e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 86824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 86924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 87024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 87124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 87224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 873e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 874e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getMetadata(); 875e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 876e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getMetadata. " + e); 877e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 87824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 87924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 88024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 88124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 882aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 883e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 884e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueue(); 885e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 886e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueue. " + e); 887e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 888aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 889aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 890aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 891aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 892aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 893e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 894e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueueTitle(); 895e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 896e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueueTitle. " + e); 897e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 898aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 899aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 900aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 901aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 902aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 903e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 904e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getExtras(); 905e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 906e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getExtras. " + e); 907e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 908aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 909aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 910aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 911aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 91224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 913e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 914e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getRatingType(); 915e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 916e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getRatingType. " + e); 917e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 91824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return 0; 91924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 92024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 92124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 922aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 923e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 924e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getFlags(); 925e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 926e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getFlags. " + e); 927e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 928aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return 0; 929aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 930aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 931aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 932312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 933e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 934e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik ParcelableVolumeInfo info = mBinder.getVolumeAttributes(); 935e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik PlaybackInfo pi = new PlaybackInfo(info.volumeType, info.audioStream, 936e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik info.controlType, info.maxVolume, info.currentVolume); 937e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return pi; 938e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 939e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackInfo. " + e); 940e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 94124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 94224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 94324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 94424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 945aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 946e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 947e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getLaunchPendingIntent(); 948e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 949e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getSessionActivity. " + e); 950e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 951aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 952aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 953aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 954aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 955aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 956e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 957e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.setVolumeTo(value, flags, null); 958e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 959e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setVolumeTo. " + e); 960e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 961aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 962aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 963aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 964aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 965e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 966e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.adjustVolume(direction, flags, null); 967e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 968e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in adjustVolume. " + e); 969e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 970aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 971aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 972aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 973b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 974e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 975e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCommand(command, params, 976e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik new MediaSessionCompat.ResultReceiverWrapper(cb)); 977e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 978e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCommand. " + e); 979e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 98024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 98124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 98224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 983aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 984e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 985e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPackageName(); 986e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 987e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPackageName. " + e); 988e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 989aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 990aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 991aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 992aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 99324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 99424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 99524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 99624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 99724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 998e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik static class TransportControlsBase extends TransportControls { 999e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 1000e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1001e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public TransportControlsBase(IMediaSession binder) { 1002e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = binder; 1003e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1004e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1005e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1006e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void play() { 1007e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1008e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.play(); 1009e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1010e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in play. " + e); 1011e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1012e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1013e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1014e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1015e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1016e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1017e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromMediaId(mediaId, extras); 1018e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1019e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromMediaId. " + e); 1020e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1021e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1022e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1023e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1024e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromSearch(String query, Bundle extras) { 1025e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1026e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromSearch(query, extras); 1027e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1028e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromSearch. " + e); 1029e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1030e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1031e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1032e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1033b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1034b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake try { 1035b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake mBinder.playFromUri(uri, extras); 1036b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } catch (RemoteException e) { 1037b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake Log.e(TAG, "Dead object in playFromUri. " + e); 1038b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1039b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1040b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1041b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1042e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToQueueItem(long id) { 1043e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1044e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.skipToQueueItem(id); 1045e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1046e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToQueueItem. " + e); 1047e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1048e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1049e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1050e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1051e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void pause() { 1052e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1053e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.pause(); 1054e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1055e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in pause. " + e); 1056e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1057e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1058e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1059e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1060e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void stop() { 1061e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1062e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.stop(); 1063e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1064e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in stop. " + e); 1065e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1066e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1067e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1068e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1069e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void seekTo(long pos) { 1070e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1071e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.seekTo(pos); 1072e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1073e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in seekTo. " + e); 1074e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1075e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1076e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1077e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1078e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void fastForward() { 1079e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1080e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.fastForward(); 1081e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1082e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in fastForward. " + e); 1083e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1084e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1085e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1086e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1087e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToNext() { 1088e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1089e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.next(); 1090e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1091e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToNext. " + e); 1092e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1093e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1094e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1095e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1096e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void rewind() { 1097e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1098e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rewind(); 1099e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1100e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in rewind. " + e); 1101e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1102e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1103e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1104e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1105e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToPrevious() { 1106e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1107e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.previous(); 1108e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1109e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToPrevious. " + e); 1110e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1111e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1112e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1113e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1114e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void setRating(RatingCompat rating) { 1115e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1116e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rate(rating); 1117e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1118e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setRating. " + e); 1119e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1120e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1121e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1122e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1123e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1124e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik sendCustomAction(customAction.getAction(), args); 1125e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1126e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1127e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1128e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(String action, Bundle args) { 1129e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1130e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCustomAction(action, args); 1131e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1132e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCustomAction. " + e); 1133e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1134e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1135e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1136e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 113724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplApi21 implements MediaControllerImpl { 1138b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake protected final Object mControllerObj; 113924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat session) { 11415c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 114224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown session.getSessionToken().getToken()); 114324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 114424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken) 114624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 11475c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 114824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown sessionToken.getToken()); 114924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mControllerObj == null) throw new RemoteException(); 115024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 115224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 115316ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 115416ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.registerCallback(mControllerObj, callback.mCallbackObj, handler); 115524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 115724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 115816ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 115916ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.unregisterCallback(mControllerObj, callback.mCallbackObj); 116024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 116124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 116224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 116324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 116424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.dispatchMediaButtonEvent(mControllerObj, event); 116524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 116624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 116724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 116824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 11691435afe32073dee10e721dfb6122ce6a194a6412RoboErik Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 117024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return controlsObj != null ? new TransportControlsApi21(controlsObj) : null; 117124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 117224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 117324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 117424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 117524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object stateObj = MediaControllerCompatApi21.getPlaybackState(mControllerObj); 117624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return stateObj != null ? PlaybackStateCompat.fromPlaybackState(stateObj) : null; 117724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 117824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 117924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 118024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 118124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object metadataObj = MediaControllerCompatApi21.getMetadata(mControllerObj); 118224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return metadataObj != null ? MediaMetadataCompat.fromMediaMetadata(metadataObj) : null; 118324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 118424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 118524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1186aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 1187aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<Object> queueObjs = MediaControllerCompatApi21.getQueue(mControllerObj); 1188aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik if (queueObjs == null) { 1189aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 1190aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1191aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> queue = 1192aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik new ArrayList<MediaSessionCompat.QueueItem>(); 1193aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik for (Object item : queueObjs) { 1194aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik queue.add(MediaSessionCompat.QueueItem.obtain(item)); 1195aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1196aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return queue; 1197aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1198aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1199aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1200aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 1201aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getQueueTitle(mControllerObj); 1202aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1203aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1204aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1205aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 1206aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getExtras(mControllerObj); 1207aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1208aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1209aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 121024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 121124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.getRatingType(mControllerObj); 121224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 121324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 121424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1215aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 1216aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getFlags(mControllerObj); 1217aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1218aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1219aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1220312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 1221312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik Object volumeInfoObj = MediaControllerCompatApi21.getPlaybackInfo(mControllerObj); 1222312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return volumeInfoObj != null ? new PlaybackInfo( 1223312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getPlaybackType(volumeInfoObj), 1224312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getLegacyAudioStream(volumeInfoObj), 1225312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getVolumeControl(volumeInfoObj), 1226312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getMaxVolume(volumeInfoObj), 1227312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getCurrentVolume(volumeInfoObj)) : null; 122824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 122924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 123024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1231aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 1232aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getSessionActivity(mControllerObj); 1233aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1234aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1235aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1236aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 1237aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.setVolumeTo(mControllerObj, value, flags); 1238aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1239aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1240aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1241aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 1242aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.adjustVolume(mControllerObj, direction, flags); 1243aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1244aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1245aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1246b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 1247b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal MediaControllerCompatApi21.sendCommand(mControllerObj, command, params, cb); 124824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 124924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 125024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1251aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 1252aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getPackageName(mControllerObj); 1253aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1254aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1255aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 125624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 125724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mControllerObj; 125824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 125924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class TransportControlsApi21 extends TransportControls { 1262b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake protected final Object mControlsObj; 126324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControlsApi21(Object controlsObj) { 126524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mControlsObj = controlsObj; 126624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 126924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void play() { 127024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.play(mControlsObj); 127124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void pause() { 127524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.pause(mControlsObj); 127624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void stop() { 128024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.stop(mControlsObj); 128124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void seekTo(long pos) { 128524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.seekTo(mControlsObj, pos); 128624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void fastForward() { 129024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.fastForward(mControlsObj); 129124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 129224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 129324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 129424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void rewind() { 129524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.rewind(mControlsObj); 129624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 129724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 129824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 129924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToNext() { 130024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToNext(mControlsObj); 130124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 130224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 130324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 130424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToPrevious() { 130524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToPrevious(mControlsObj); 130624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 130724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 130824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 130924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void setRating(RatingCompat rating) { 131024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.setRating(mControlsObj, 131124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown rating != null ? rating.getRating() : null); 131224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 1313aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1314aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1315aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1316aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromMediaId(mControlsObj, mediaId, 1317aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1318aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1319aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1320aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1321aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromSearch(String query, Bundle extras) { 1322aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromSearch(mControlsObj, query, 1323aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1324aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1325aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1326aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1327b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1328b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1329b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1330b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1331aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void skipToQueueItem(long id) { 1332aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.skipToQueueItem(mControlsObj, id); 1333aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1334aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1335aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1336aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1337aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, 1338aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik customAction.getAction(), args); 1339aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1340aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1341aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1342aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(String action, Bundle args) { 1343aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, action, 1344aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik args); 1345aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 134624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 1347b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1348b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake static class MediaControllerImplApi23 extends MediaControllerImplApi21 { 1349b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1350b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public MediaControllerImplApi23(Context context, MediaSessionCompat session) { 1351b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(context, session); 1352b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1353b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1354b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public MediaControllerImplApi23(Context context, MediaSessionCompat.Token sessionToken) 1355b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake throws RemoteException { 1356b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(context, sessionToken); 1357b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1358b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1359b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1360b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public TransportControls getTransportControls() { 1361b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 1362b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake return controlsObj != null ? new TransportControlsApi23(controlsObj) : null; 1363b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1364b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1365b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1366b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake static class TransportControlsApi23 extends TransportControlsApi21 { 1367b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1368b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public TransportControlsApi23(Object controlsObj) { 1369b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake super(controlsObj); 1370b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1371b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake 1372b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake @Override 1373b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake public void playFromUri(Uri uri, Bundle extras) { 1374b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake MediaControllerCompatApi23.TransportControls.playFromUri(mControlsObj, uri, 1375b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake extras); 1376b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 1377b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake } 137824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 1379