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 7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, session); 7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 75e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mImpl = new MediaControllerImplBase(mToken); 7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 7924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Creates a media controller from a session token which may have 8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * been obtained from another process. 8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param sessionToken The token of the session to be controlled. 8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @throws RemoteException if the session is not accessible. 8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerCompat(Context context, MediaSessionCompat.Token sessionToken) 8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (sessionToken == null) { 8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("sessionToken must not be null"); 9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9194be6100218126ce6a08bf1f56209578500b361fRoboErik mToken = sessionToken; 9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, sessionToken); 9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 96e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mImpl = new MediaControllerImplBase(mToken); 9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get a {@link TransportControls} instance for this session. 10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return A controls instance 10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getTransportControls(); 10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Send the specified media button event to the session. Only media keys can 11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * be sent by this method, other keys will be ignored. 11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param keyEvent The media button event to dispatch. 11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return true if the event was sent to the session, false otherwise. 11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 11624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { 11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (keyEvent == null) { 11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("KeyEvent may not be null"); 11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.dispatchMediaButtonEvent(keyEvent); 12124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 12424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current playback state for this session. 12524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 12624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current PlaybackState or null 12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getPlaybackState(); 13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current metadata for this session. 13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current MediaMetadata or null. 13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMetadata(); 13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 14124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 142aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the current play queue for this session if one is set. If you only 143aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * care about the current item {@link #getMetadata()} should be used. 144aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 145aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The current play queue or null. 146aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 147aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 148aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getQueue(); 149aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 150aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 151aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 152aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the queue title for this session. 153aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 154aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 155aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getQueueTitle(); 156aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 157aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 158aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 159aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the extras for this session. 160aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 161aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 162aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getExtras(); 163aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 164aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 165aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the rating type supported by the session. One of: 16724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_NONE}</li> 16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_HEART}</li> 17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_THUMB_UP_DOWN}</li> 17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_3_STARS}</li> 17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_4_STARS}</li> 17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_5_STARS}</li> 17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_PERCENTAGE}</li> 17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The supported rating type 17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getRatingType(); 18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 184aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the flags for this session. Flags are defined in 185aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat}. 186aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 187aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The current set of flags for the session. 188aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 189aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 190aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getFlags(); 191aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 192aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 193aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 194312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * Get the current playback info for this session. 19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 196312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * @return The current playback info or null. 19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 198312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 199312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return mImpl.getPlaybackInfo(); 20024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 20124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 203aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get an intent for launching UI associated with this session if one 204aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * exists. 205aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 206aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return A {@link PendingIntent} to launch UI or null. 207aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 208aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 209aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getSessionActivity(); 210aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 211aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 212aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 21394be6100218126ce6a08bf1f56209578500b361fRoboErik * Get the token for the session this controller is connected to. 21494be6100218126ce6a08bf1f56209578500b361fRoboErik * 21594be6100218126ce6a08bf1f56209578500b361fRoboErik * @return The session's token. 21694be6100218126ce6a08bf1f56209578500b361fRoboErik */ 21794be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getSessionToken() { 21894be6100218126ce6a08bf1f56209578500b361fRoboErik return mToken; 21994be6100218126ce6a08bf1f56209578500b361fRoboErik } 22094be6100218126ce6a08bf1f56209578500b361fRoboErik 22194be6100218126ce6a08bf1f56209578500b361fRoboErik /** 222aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Set the volume of the output this session is playing on. The command will 223aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * be ignored if it does not support 224aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}. The flags in 225aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager} may be used to affect the handling. 226aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 227aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #getPlaybackInfo() 228aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param value The value to set it to, between 0 and the reported max. 229aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param flags Flags from {@link AudioManager} to include with the volume 230aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * request. 231aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 232aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 233aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik mImpl.setVolumeTo(value, flags); 234aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 235aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 236aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 237aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Adjust the volume of the output this session is playing on. The direction 238aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * must be one of {@link AudioManager#ADJUST_LOWER}, 239aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}. 240aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * The command will be ignored if the session does not support 241aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE} or 242aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}. The flags in 243aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link AudioManager} may be used to affect the handling. 244aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 245aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #getPlaybackInfo() 246aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param direction The direction to adjust the volume in. 247aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param flags Any flags to pass with the command. 248aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 249aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 250aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik mImpl.adjustVolume(direction, flags); 251aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 252aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 253aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 25424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the Session. Updates will be 25524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the caller's thread. 25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 25916ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback) { 26016ac83bebda2a19930b9d692789f3b507c49951bRoboErik registerCallback(callback, null); 26124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 26224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the session. Updates will be 26524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the specified handler's thread. 26624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 26724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param handler The handler to post updates on. If null the callers thread 26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * will be used. 27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 27116ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 27224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 27324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 27424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (handler == null) { 27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown handler = new Handler(); 27724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 27816ac83bebda2a19930b9d692789f3b507c49951bRoboErik mImpl.registerCallback(callback, handler); 27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 28224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Stop receiving updates on the specified callback. If an update has 28324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * already been posted you may still receive it after calling this method. 28424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 28524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback to remove 28624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 28716ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 28824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 28924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 29024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29116ac83bebda2a19930b9d692789f3b507c49951bRoboErik mImpl.unregisterCallback(callback); 29224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 29524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Sends a generic command to the session. It is up to the session creator 29624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to decide what commands and parameters they will support. As such, 29724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * commands should only be sent to sessions that the controller owns. 29824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 29924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param command The command to send 30024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param params Any parameters to include with the command 30124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param cb The callback to receive the result on 30224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 303b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 30424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (TextUtils.isEmpty(command)) { 30524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("command cannot be null or empty"); 30624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 307b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal mImpl.sendCommand(command, params, cb); 30824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 30924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 31024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 311aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Get the session owner's package name. 312aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 313aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The package name of of the session owner. 314aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 315aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 316aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return mImpl.getPackageName(); 317aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 318aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 319aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 320aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Gets the underlying framework 321aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link android.media.session.MediaController} object. 32224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 32324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * This method is only supported on API 21+. 32424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </p> 32524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 326aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @return The underlying {@link android.media.session.MediaController} 327aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * object, or null if none. 32824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 32924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 33024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMediaController(); 33124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 33224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 33324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 33424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Callback for receiving updates on from the session. A Callback can be 33516ac83bebda2a19930b9d692789f3b507c49951bRoboErik * registered using {@link #registerCallback} 33624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 337e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public static abstract class Callback implements IBinder.DeathRecipient { 338e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private final Object mCallbackObj; 339e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private MessageHandler mHandler; 340e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 341e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mRegistered = false; 34224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 34324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Callback() { 34424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 34524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21()); 34624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 347e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mCallbackObj = new StubCompat(); 34824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 34924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 35024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 35124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 35223138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik * Override to handle the session being destroyed. The session is no 35323138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik * longer valid after this call and calls to it will be ignored. 35423138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik */ 35523138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik public void onSessionDestroyed() { 35623138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik } 35723138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik 35823138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik /** 35924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle custom events sent by the session owner without a 36024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * specified interface. Controllers should only handle these for 36124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * sessions they own. 36224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 36324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param event The event from the session. 36424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param extras Optional parameters for the event. 36524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 36624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 36724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 36824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 36924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 37024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes in playback state. 37124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 37224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param state The new playback state of the session 37324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 37424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(PlaybackStateCompat state) { 37524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 37724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 37824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes to the current metadata. 37924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 38024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param metadata The current metadata for the session or null if none. 38124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @see MediaMetadata 38224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 38324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(MediaMetadataCompat metadata) { 38424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 38524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 386aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 387aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to items in the queue. 388aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 389aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see MediaSessionCompat.QueueItem 390aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param queue A list of items in the current play queue. It should 391aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * include the currently playing item as well as previous and 392aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * upcoming items if applicable. 393aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 394aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) { 395aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 396aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 397aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 398aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to the queue title. 399aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 400aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param title The title that should be displayed along with the play 401aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * queue such as "Now Playing". May be null if there is no 402aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * such title. 403aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 404aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onQueueTitleChanged(CharSequence title) { 405aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 406aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 407aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 408aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle chagnes to the {@link MediaSessionCompat} extras. 409aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 410aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras The extras that can include other information 411aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * associated with the {@link MediaSessionCompat}. 412aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 413aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onExtrasChanged(Bundle extras) { 414aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 415aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 416aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 417aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Override to handle changes to the audio info. 418aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 419aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param info The current audio info for this session. 420aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 421aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void onAudioInfoChanged(PlaybackInfo info) { 422aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 423aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 424e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 425e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void binderDied() { 426e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionDestroyed(); 427e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 428e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 429e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik /** 430e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik * Set the handler to use for pre 21 callbacks. 431e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik */ 432e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setHandler(Handler handler) { 433e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler = new MessageHandler(handler.getLooper()); 434e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 435e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 43624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private class StubApi21 implements MediaControllerCompatApi21.Callback { 43724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 43823138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik public void onSessionDestroyed() { 43923138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik Callback.this.onSessionDestroyed(); 44023138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik } 44123138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik 44223138c4b9be07abdab0cfdde2c62186359c9e7faRoboErik @Override 44324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 44424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onSessionEvent(event, extras); 44524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 44724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 44824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(Object stateObj) { 44924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onPlaybackStateChanged( 45024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat.fromPlaybackState(stateObj)); 45124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 45224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 45324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 45424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(Object metadataObj) { 45524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onMetadataChanged( 45624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat.fromMediaMetadata(metadataObj)); 45724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 45824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 459e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 460e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private class StubCompat extends IMediaControllerCallback.Stub { 461e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 462e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 463e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onEvent(String event, Bundle extras) throws RemoteException { 464e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_EVENT, event, extras); 465e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 466e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 467e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 468e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onSessionDestroyed() throws RemoteException { 469e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_DESTROYED, null, null); 470e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 471e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 472e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 473e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) throws RemoteException { 474e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE, state, null); 475e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 476e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 477e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 478e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) throws RemoteException { 479e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_METADATA, metadata, null); 480e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 481e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 482e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 483e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onQueueChanged(List<QueueItem> queue) throws RemoteException { 484e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_QUEUE, queue, null); 485e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 486e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 487e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 488e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onQueueTitleChanged(CharSequence title) throws RemoteException { 489e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_QUEUE_TITLE, title, null); 490e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 491e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 492e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 493e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onExtrasChanged(Bundle extras) throws RemoteException { 494e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS, extras, null); 495e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 496e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 497e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 498e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException { 499e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik PlaybackInfo pi = null; 500e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (info != null) { 501e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik pi = new PlaybackInfo(info.volumeType, info.audioStream, info.controlType, 502e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik info.maxVolume, info.currentVolume); 503e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 504e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mHandler.post(MessageHandler.MSG_UPDATE_VOLUME, pi, null); 505e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 506e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 507e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 508e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private class MessageHandler extends Handler { 509e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_EVENT = 1; 510e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_PLAYBACK_STATE = 2; 511e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_METADATA = 3; 512e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_VOLUME = 4; 513e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_QUEUE = 5; 514e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_QUEUE_TITLE = 6; 515e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_UPDATE_EXTRAS = 7; 516e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private static final int MSG_DESTROYED = 8; 517e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 518e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public MessageHandler(Looper looper) { 519e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik super(looper); 520e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 521e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 522e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 523e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void handleMessage(Message msg) { 524e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mRegistered) { 525e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 526e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 527e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik switch (msg.what) { 528e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_EVENT: 529e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionEvent((String) msg.obj, msg.getData()); 530e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 531e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_PLAYBACK_STATE: 532e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onPlaybackStateChanged((PlaybackStateCompat) msg.obj); 533e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 534e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_METADATA: 535e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onMetadataChanged((MediaMetadataCompat) msg.obj); 536e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 537e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_QUEUE: 538e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onQueueChanged((List<MediaSessionCompat.QueueItem>) msg.obj); 539e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 540e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_QUEUE_TITLE: 541e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onQueueTitleChanged((CharSequence) msg.obj); 542e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 543e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_EXTRAS: 544e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onExtrasChanged((Bundle) msg.obj); 545e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 546e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_UPDATE_VOLUME: 547e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onAudioInfoChanged((PlaybackInfo) msg.obj); 548e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 549e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik case MSG_DESTROYED: 550e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik onSessionDestroyed(); 551e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik break; 552e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 553e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 554e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 555e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void post(int what, Object obj, Bundle data) { 556e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik obtainMessage(what, obj).sendToTarget(); 557e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 558e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 55924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 56024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 56124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 56224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Interface for controlling media playback on a session. This allows an app 56324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to send media transport commands to the session. 56424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 56524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static abstract class TransportControls { 56624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls() { 56724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 56824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 56924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 57024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player start its playback at its current position. 57124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 57224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void play(); 57324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 57424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 575aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Request that the player start playback for a specific {@link Uri}. 576aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 577aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param mediaId The uri of the requested media. 578aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras Optional extras that can include extra information 579aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * about the media item to be played. 580aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 581aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void playFromMediaId(String mediaId, Bundle extras); 582aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 583aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 584aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Request that the player start playback for a specific search query. 585aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * An empty or null query should be treated as a request to play any 586aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * music. 587aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 588aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param query The search query. 589aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param extras Optional extras that can include extra information 590aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * about the query. 591aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 592aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void playFromSearch(String query, Bundle extras); 593aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 594aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 595aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Play an item with a specific id in the play queue. If you specify an 596aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * id that is not in the play queue, the behavior is undefined. 597aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 598aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void skipToQueueItem(long id); 599aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 600aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 60124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player pause its playback and stay at its current 60224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * position. 60324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 60424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void pause(); 60524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 60624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 60724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player stop its playback; it may clear its state in 60824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * whatever way is appropriate. 60924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 61024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void stop(); 61124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 61224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 61324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Move to a new location in the media stream. 61424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 61524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param pos Position to move to, in milliseconds. 61624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 61724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void seekTo(long pos); 61824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 61924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 62024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start fast forwarding. If playback is already fast forwarding this 62124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * may increase the rate. 62224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 62324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void fastForward(); 62424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 62524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 62624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the next item. 62724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 62824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToNext(); 62924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 63124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start rewinding. If playback is already rewinding this may increase 63224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the rate. 63324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void rewind(); 63524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 63624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 63724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the previous item. 63824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 63924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToPrevious(); 64024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 64124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 64224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Rate the current content. This will cause the rating to be set for 64324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the current user. The Rating type must match the type returned by 64424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * {@link #getRatingType()}. 64524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 64624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param rating The rating to set for the current content 64724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 64824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void setRating(RatingCompat rating); 649aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 650aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 651aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send a custom action for the {@link MediaSessionCompat} to perform. 652aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 653aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param customAction The action to perform. 654aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 655aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 656aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 657aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(PlaybackStateCompat.CustomAction customAction, 658aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle args); 659aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 660aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik /** 661aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Send the id and args from a custom action for the 662aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} to perform. 663aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * 664aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @see #sendCustomAction(PlaybackStateCompat.CustomAction action, 665aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * Bundle args) 666aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param action The action identifier of the 667aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link PlaybackStateCompat.CustomAction} as specified by 668aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * the {@link MediaSessionCompat}. 669aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * @param args Optional arguments to supply to the 670aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik * {@link MediaSessionCompat} for this custom action. 671aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik */ 672aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public abstract void sendCustomAction(String action, Bundle args); 67324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 67424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 67524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 67624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Holds information about the way volume is handled for this session. 67724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 678312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final class PlaybackInfo { 679312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 680312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses local playback. 681312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 682312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_LOCAL = 1; 683312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik /** 684312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * The session uses remote playback. 685312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik */ 686312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public static final int PLAYBACK_TYPE_REMOTE = 2; 687312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik 688312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik private final int mPlaybackType; 6891435afe32073dee10e721dfb6122ce6a194a6412RoboErik // TODO update audio stream with AudioAttributes support version 69024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mAudioStream; 69124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mVolumeControl; 69224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mMaxVolume; 69324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mCurrentVolume; 69424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 695312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo(int type, int stream, int control, int max, int current) { 696312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik mPlaybackType = type; 69724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mAudioStream = stream; 69824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mVolumeControl = control; 69924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mMaxVolume = max; 70024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCurrentVolume = current; 70124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 70224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 70324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 70424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume handling, either local or remote. One of: 70524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 706312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_LOCAL}</li> 707312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * <li>{@link PlaybackInfo#PLAYBACK_TYPE_REMOTE}</li> 70824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 70924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 71024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume handling this session is using. 71124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 712312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public int getPlaybackType() { 713312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return mPlaybackType; 71424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 71524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 71624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 71724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the stream this is currently controlling volume on. When the volume 718312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik * type is {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} this value does not 71924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * have meaning and should be ignored. 72024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 72124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The stream this session is playing on. 72224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 72324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getAudioStream() { 724aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik // TODO switch to AudioAttributesCompat when it is added. 72524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mAudioStream; 72624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 72724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 72824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 72924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume control that can be used. One of: 73024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 73124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}</li> 73224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE}</li> 73324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_FIXED}</li> 73424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 73524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 73624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume control that may be used with this 73724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * session. 73824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 73924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getVolumeControl() { 74024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mVolumeControl; 74124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 74224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 74324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 74424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the maximum volume that may be set for this session. 74524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 74624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The maximum allowed volume where this session is playing. 74724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 74824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getMaxVolume() { 74924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mMaxVolume; 75024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 75124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 75224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 75324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current volume for this session. 75424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 75524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current volume where this session is playing. 75624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 75724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getCurrentVolume() { 75824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mCurrentVolume; 75924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 76024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 76124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 76224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown interface MediaControllerImpl { 76316ac83bebda2a19930b9d692789f3b507c49951bRoboErik void registerCallback(Callback callback, Handler handler); 76416ac83bebda2a19930b9d692789f3b507c49951bRoboErik 76516ac83bebda2a19930b9d692789f3b507c49951bRoboErik void unregisterCallback(Callback callback); 76624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown boolean dispatchMediaButtonEvent(KeyEvent keyEvent); 76724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls getTransportControls(); 76824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat getPlaybackState(); 76924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat getMetadata(); 770aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 771aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> getQueue(); 772aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik CharSequence getQueueTitle(); 773aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik Bundle getExtras(); 77424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int getRatingType(); 775aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik long getFlags(); 776312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik PlaybackInfo getPlaybackInfo(); 777aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik PendingIntent getSessionActivity(); 778aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 779aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void setVolumeTo(int value, int flags); 780aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik void adjustVolume(int direction, int flags); 781b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal void sendCommand(String command, Bundle params, ResultReceiver cb); 782aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 783aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik String getPackageName(); 78424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object getMediaController(); 78524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 78624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 78724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplBase implements MediaControllerImpl { 788e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private MediaSessionCompat.Token mToken; 789e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 790e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private TransportControls mTransportControls; 791e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 792e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public MediaControllerImplBase(MediaSessionCompat.Token token) { 793e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mToken = token; 794e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken()); 795e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 796e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 79724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 79816ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 799e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 800e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 801e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 802e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 803e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().linkToDeath(callback, 0); 804e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.registerCallbackListener((IMediaControllerCallback) callback.mCallbackObj); 805e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.setHandler(handler); 806e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = true; 807e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 808e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in registerCallback. " + e); 809e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.onSessionDestroyed(); 810e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 81124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 81224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 81324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 81416ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 815e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (callback == null) { 816e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("callback may not be null."); 817e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 818e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 819e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.unregisterCallbackListener( 820e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik (IMediaControllerCallback) callback.mCallbackObj); 821e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.asBinder().unlinkToDeath(callback, 0); 822e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik callback.mRegistered = false; 823e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 824e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in unregisterCallback. " + e); 825e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 82624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 82724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 82824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 82924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 830e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (event == null) { 831e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik throw new IllegalArgumentException("event may not be null."); 832e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 833e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 834e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendMediaButton(event); 835e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 836e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in dispatchMediaButtonEvent. " + e); 837e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 83824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return false; 83924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 84024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 84124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 84224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 843e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (mTransportControls == null) { 844e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mTransportControls = new TransportControlsBase(mBinder); 845e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 846e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 847e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mTransportControls; 84824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 84924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 85024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 85124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 852e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 853e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPlaybackState(); 854e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 855e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackState. " + e); 856e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 85724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 85824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 85924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 86024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 86124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 862e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 863e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getMetadata(); 864e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 865e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getMetadata. " + e); 866e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 86724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 86824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 86924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 87024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 871aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 872e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 873e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueue(); 874e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 875e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueue. " + e); 876e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 877aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 878aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 879aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 880aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 881aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 882e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 883e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getQueueTitle(); 884e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 885e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getQueueTitle. " + e); 886e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 887aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 888aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 889aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 890aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 891aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 892e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 893e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getExtras(); 894e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 895e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getExtras. " + e); 896e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 897aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 898aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 899aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 900aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 90124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 902e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 903e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getRatingType(); 904e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 905e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getRatingType. " + e); 906e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 90724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return 0; 90824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 90924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 91024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 911aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 912e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 913e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getFlags(); 914e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 915e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getFlags. " + e); 916e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 917aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return 0; 918aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 919aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 920aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 921312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 922e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 923e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik ParcelableVolumeInfo info = mBinder.getVolumeAttributes(); 924e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik PlaybackInfo pi = new PlaybackInfo(info.volumeType, info.audioStream, 925e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik info.controlType, info.maxVolume, info.currentVolume); 926e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return pi; 927e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 928e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPlaybackInfo. " + e); 929e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 93024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 93124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 93224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 93324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 934aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 935e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 936e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getLaunchPendingIntent(); 937e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 938e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getSessionActivity. " + e); 939e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 940aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 941aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 942aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 943aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 944aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 945e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 946e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.setVolumeTo(value, flags, null); 947e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 948e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setVolumeTo. " + e); 949e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 950aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 951aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 952aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 953aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 954e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 955e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.adjustVolume(direction, flags, null); 956e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 957e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in adjustVolume. " + e); 958e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 959aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 960aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 961aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 962b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 963e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 964e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCommand(command, params, 965e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik new MediaSessionCompat.ResultReceiverWrapper(cb)); 966e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 967e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCommand. " + e); 968e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 96924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 97024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 97124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 972aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 973e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 974e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return mBinder.getPackageName(); 975e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 976e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in getPackageName. " + e); 977e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 978aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 979aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 980aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 981aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 98224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 98324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 98424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 98524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 98624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 987e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik static class TransportControlsBase extends TransportControls { 988e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private IMediaSession mBinder; 989e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 990e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public TransportControlsBase(IMediaSession binder) { 991e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder = binder; 992e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 993e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 994e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 995e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void play() { 996e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 997e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.play(); 998e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 999e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in play. " + e); 1000e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1001e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1002e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1003e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1004e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1005e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1006e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromMediaId(mediaId, extras); 1007e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1008e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromMediaId. " + e); 1009e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1010e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1011e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1012e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1013e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void playFromSearch(String query, Bundle extras) { 1014e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1015e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.playFromSearch(query, extras); 1016e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1017e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in playFromSearch. " + e); 1018e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1019e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1020e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1021e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1022e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToQueueItem(long id) { 1023e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1024e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.skipToQueueItem(id); 1025e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1026e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToQueueItem. " + e); 1027e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1028e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1029e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1030e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1031e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void pause() { 1032e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1033e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.pause(); 1034e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1035e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in pause. " + e); 1036e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1037e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1038e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1039e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1040e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void stop() { 1041e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1042e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.stop(); 1043e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1044e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in stop. " + e); 1045e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1046e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1047e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1048e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1049e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void seekTo(long pos) { 1050e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1051e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.seekTo(pos); 1052e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1053e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in seekTo. " + e); 1054e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1055e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1056e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1057e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1058e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void fastForward() { 1059e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1060e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.fastForward(); 1061e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1062e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in fastForward. " + e); 1063e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1064e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1065e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1066e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1067e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToNext() { 1068e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1069e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.next(); 1070e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1071e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToNext. " + e); 1072e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1073e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1074e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1075e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1076e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void rewind() { 1077e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1078e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rewind(); 1079e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1080e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in rewind. " + e); 1081e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1082e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1083e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1084e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1085e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void skipToPrevious() { 1086e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1087e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.previous(); 1088e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1089e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in skipToPrevious. " + e); 1090e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1091e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1092e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1093e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1094e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void setRating(RatingCompat rating) { 1095e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1096e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.rate(rating); 1097e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1098e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in setRating. " + e); 1099e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1100e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1101e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1102e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1103e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1104e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik sendCustomAction(customAction.getAction(), args); 1105e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1106e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 1107e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik @Override 1108e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik public void sendCustomAction(String action, Bundle args) { 1109e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik try { 1110e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mBinder.sendCustomAction(action, args); 1111e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } catch (RemoteException e) { 1112e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik Log.e(TAG, "Dead object in sendCustomAction. " + e); 1113e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1114e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1115e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 1116e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik 111724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplApi21 implements MediaControllerImpl { 111824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final Object mControllerObj; 111924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 112024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat session) { 11215c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 112224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown session.getSessionToken().getToken()); 112324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 112424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 112524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken) 112624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 11275c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 112824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown sessionToken.getToken()); 112924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mControllerObj == null) throw new RemoteException(); 113024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 113124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 113224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 113316ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void registerCallback(Callback callback, Handler handler) { 113416ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.registerCallback(mControllerObj, callback.mCallbackObj, handler); 113524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 113624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 113724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 113816ac83bebda2a19930b9d692789f3b507c49951bRoboErik public void unregisterCallback(Callback callback) { 113916ac83bebda2a19930b9d692789f3b507c49951bRoboErik MediaControllerCompatApi21.unregisterCallback(mControllerObj, callback.mCallbackObj); 114024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 114124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 114324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 114424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.dispatchMediaButtonEvent(mControllerObj, event); 114524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 114624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 114724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 114824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 11491435afe32073dee10e721dfb6122ce6a194a6412RoboErik Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 115024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return controlsObj != null ? new TransportControlsApi21(controlsObj) : null; 115124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 115324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 115424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 115524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object stateObj = MediaControllerCompatApi21.getPlaybackState(mControllerObj); 115624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return stateObj != null ? PlaybackStateCompat.fromPlaybackState(stateObj) : null; 115724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 115824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 115924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 116024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 116124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object metadataObj = MediaControllerCompatApi21.getMetadata(mControllerObj); 116224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return metadataObj != null ? MediaMetadataCompat.fromMediaMetadata(metadataObj) : null; 116324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 116424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 116524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1166aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public List<MediaSessionCompat.QueueItem> getQueue() { 1167aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<Object> queueObjs = MediaControllerCompatApi21.getQueue(mControllerObj); 1168aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik if (queueObjs == null) { 1169aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return null; 1170aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1171aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik List<MediaSessionCompat.QueueItem> queue = 1172aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik new ArrayList<MediaSessionCompat.QueueItem>(); 1173aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik for (Object item : queueObjs) { 1174aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik queue.add(MediaSessionCompat.QueueItem.obtain(item)); 1175aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1176aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return queue; 1177aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1178aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1179aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1180aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public CharSequence getQueueTitle() { 1181aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getQueueTitle(mControllerObj); 1182aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1183aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1184aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1185aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public Bundle getExtras() { 1186aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getExtras(mControllerObj); 1187aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1188aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1189aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 119024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 119124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.getRatingType(mControllerObj); 119224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 119324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 119424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1195aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public long getFlags() { 1196aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getFlags(mControllerObj); 1197aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1198aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1199aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1200312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik public PlaybackInfo getPlaybackInfo() { 1201312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik Object volumeInfoObj = MediaControllerCompatApi21.getPlaybackInfo(mControllerObj); 1202312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik return volumeInfoObj != null ? new PlaybackInfo( 1203312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getPlaybackType(volumeInfoObj), 1204312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getLegacyAudioStream(volumeInfoObj), 1205312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getVolumeControl(volumeInfoObj), 1206312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getMaxVolume(volumeInfoObj), 1207312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik MediaControllerCompatApi21.PlaybackInfo.getCurrentVolume(volumeInfoObj)) : null; 120824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 120924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 121024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1211aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public PendingIntent getSessionActivity() { 1212aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getSessionActivity(mControllerObj); 1213aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1214aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1215aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1216aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void setVolumeTo(int value, int flags) { 1217aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.setVolumeTo(mControllerObj, value, flags); 1218aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1219aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1220aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1221aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void adjustVolume(int direction, int flags) { 1222aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.adjustVolume(mControllerObj, direction, flags); 1223aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1224aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1225aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1226b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 1227b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal MediaControllerCompatApi21.sendCommand(mControllerObj, command, params, cb); 122824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 122924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 123024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 1231aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public String getPackageName() { 1232aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik return MediaControllerCompatApi21.getPackageName(mControllerObj); 1233aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1234aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1235aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 123624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 123724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mControllerObj; 123824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 123924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 124024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 124124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class TransportControlsApi21 extends TransportControls { 124224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final Object mControlsObj; 124324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 124424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControlsApi21(Object controlsObj) { 124524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mControlsObj = controlsObj; 124624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 124724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 124824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 124924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void play() { 125024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.play(mControlsObj); 125124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 125224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 125324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 125424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void pause() { 125524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.pause(mControlsObj); 125624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 125724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 125824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 125924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void stop() { 126024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.stop(mControlsObj); 126124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 126424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void seekTo(long pos) { 126524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.seekTo(mControlsObj, pos); 126624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 126724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 126824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 126924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void fastForward() { 127024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.fastForward(mControlsObj); 127124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void rewind() { 127524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.rewind(mControlsObj); 127624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 127724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 127824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 127924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToNext() { 128024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToNext(mControlsObj); 128124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToPrevious() { 128524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToPrevious(mControlsObj); 128624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 128724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 128824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 128924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void setRating(RatingCompat rating) { 129024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.setRating(mControlsObj, 129124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown rating != null ? rating.getRating() : null); 129224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 1293aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1294aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1295aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromMediaId(String mediaId, Bundle extras) { 1296aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromMediaId(mControlsObj, mediaId, 1297aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1298aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1299aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1300aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1301aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void playFromSearch(String query, Bundle extras) { 1302aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.playFromSearch(mControlsObj, query, 1303aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik extras); 1304aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1305aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1306aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1307aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void skipToQueueItem(long id) { 1308aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.skipToQueueItem(mControlsObj, id); 1309aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1310aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1311aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1312aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(CustomAction customAction, Bundle args) { 1313aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, 1314aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik customAction.getAction(), args); 1315aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 1316aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik 1317aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik @Override 1318aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik public void sendCustomAction(String action, Bundle args) { 1319aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik MediaControllerCompatApi21.TransportControls.sendCustomAction(mControlsObj, action, 1320aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik args); 1321aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik } 132224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 132324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 1324