MediaControllerCompat.java revision 5c41750574ba65da432b69f89cd32dc356281005
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 1924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.content.Context; 2024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Bundle; 2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Handler; 2224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.RemoteException; 2324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.ResultReceiver; 2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.MediaMetadataCompat; 2524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.RatingCompat; 2624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.support.v4.media.VolumeProviderCompat; 2724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.text.TextUtils; 2824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.view.KeyEvent; 2924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/** 3124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Allows an app to interact with an ongoing media session. Media buttons and 3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * other commands can be sent to the session. A callback may be registered to 3324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * receive updates from the session, such as metadata and play state changes. 3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 3524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * A MediaController can be created if you have a {@link MediaSessionCompat.Token} 3624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * from the session owner. 3724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 3824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * MediaController objects are thread-safe. 3924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 4024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * This is a helper for accessing features in {@link android.media.session.MediaSession} 4124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * introduced after API level 4 in a backwards compatible fashion. 4224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 4324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpublic final class MediaControllerCompat { 4424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final MediaControllerImpl mImpl; 4524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 4624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 4724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Creates a media controller from a session. 4824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 4924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param session The session to be controlled. 5024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 5124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerCompat(Context context, MediaSessionCompat session) { 5224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (session == null) { 5324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("session must not be null"); 5424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 5624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 5724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, session); 5824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 5924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplBase(); 6024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Creates a media controller from a session token which may have 6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * been obtained from another process. 6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 6724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param sessionToken The token of the session to be controlled. 6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @throws RemoteException if the session is not accessible. 6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerCompat(Context context, MediaSessionCompat.Token sessionToken) 7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (sessionToken == null) { 7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("sessionToken must not be null"); 7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 7724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplApi21(context, sessionToken); 7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 7924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl = new MediaControllerImplBase(); 8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get a {@link TransportControls} instance for this session. 8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return A controls instance 8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getTransportControls(); 9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 9324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Send the specified media button event to the session. Only media keys can 9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * be sent by this method, other keys will be ignored. 9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param keyEvent The media button event to dispatch. 9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return true if the event was sent to the session, false otherwise. 9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { 10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (keyEvent == null) { 10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("KeyEvent may not be null"); 10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.dispatchMediaButtonEvent(keyEvent); 10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current playback state for this session. 10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current PlaybackState or null 11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getPlaybackState(); 11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 11624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current metadata for this session. 11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current MediaMetadata or null. 11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 12124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMetadata(); 12224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 12524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the rating type supported by the session. One of: 12624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_NONE}</li> 12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_HEART}</li> 12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_THUMB_UP_DOWN}</li> 13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_3_STARS}</li> 13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_4_STARS}</li> 13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_5_STARS}</li> 13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link RatingCompat#RATING_PERCENTAGE}</li> 13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The supported rating type 13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getRatingType(); 14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 14124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 14224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 14324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current volume info for this session. 14424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 14524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current volume info or null. 14624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 14724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public VolumeInfo getVolumeInfo() { 14824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getVolumeInfo(); 14924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 15124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 15224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the Session. Updates will be 15324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the caller's thread. 15424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 15524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 15624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 15724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void addCallback(Callback callback) { 15824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown addCallback(callback, null); 15924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 16024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 16124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 16224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Adds a callback to receive updates from the session. Updates will be 16324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * posted on the specified handler's thread. 16424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 16524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback object, must not be null. 16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param handler The handler to post updates on. If null the callers thread 16724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * will be used. 16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void addCallback(Callback callback, Handler handler) { 17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (handler == null) { 17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown handler = new Handler(); 17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl.addCallback(callback, handler); 17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Stop receiving updates on the specified callback. If an update has 18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * already been posted you may still receive it after calling this method. 18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param callback The callback to remove 18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void removeCallback(Callback callback) { 18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (callback == null) { 18724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("callback cannot be null"); 18824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 18924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mImpl.removeCallback(callback); 19024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 19224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 19324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Sends a generic command to the session. It is up to the session creator 19424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to decide what commands and parameters they will support. As such, 19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * commands should only be sent to sessions that the controller owns. 19624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param command The command to send 19824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param params Any parameters to include with the command 19924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param cb The callback to receive the result on 20024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 201b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (TextUtils.isEmpty(command)) { 20324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new IllegalArgumentException("command cannot be null or empty"); 20424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 205b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal mImpl.sendCommand(command, params, cb); 20624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 20724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 20824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 20924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Gets the underlying framework {@link android.media.session.MediaController} object. 21024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <p> 21124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * This method is only supported on API 21+. 21224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </p> 21324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 21424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The underlying {@link android.media.session.MediaController} object, 21524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * or null if none. 21624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 21724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 21824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mImpl.getMediaController(); 21924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 22024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 22124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 22224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Callback for receiving updates on from the session. A Callback can be 22324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * registered using {@link #addCallback} 22424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 22524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static abstract class Callback { 22624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final Object mCallbackObj; 22724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 22824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Callback() { 22924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (android.os.Build.VERSION.SDK_INT >= 21) { 23024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21()); 23124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 23224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallbackObj = null; 23324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 23424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 23524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 23624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 23724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle custom events sent by the session owner without a 23824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * specified interface. Controllers should only handle these for 23924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * sessions they own. 24024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 24124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param event The event from the session. 24224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param extras Optional parameters for the event. 24324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 24424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 24524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 24624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 24724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 24824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes in playback state. 24924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 25024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param state The new playback state of the session 25124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 25224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(PlaybackStateCompat state) { 25324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 25424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 25524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Override to handle changes to the current metadata. 25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param metadata The current metadata for the session or null if none. 25924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @see MediaMetadata 26024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 26124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(MediaMetadataCompat metadata) { 26224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private class StubApi21 implements MediaControllerCompatApi21.Callback { 26524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 26624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onSessionEvent(String event, Bundle extras) { 26724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onSessionEvent(event, extras); 26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 27124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onPlaybackStateChanged(Object stateObj) { 27224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onPlaybackStateChanged( 27324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat.fromPlaybackState(stateObj)); 27424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 27724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onMetadataChanged(Object metadataObj) { 27824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Callback.this.onMetadataChanged( 27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat.fromMediaMetadata(metadataObj)); 28024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 28424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 28524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Interface for controlling media playback on a session. This allows an app 28624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * to send media transport commands to the session. 28724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 28824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static abstract class TransportControls { 28924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls() { 29024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 29324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player start its playback at its current position. 29424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 29524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void play(); 29624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 29824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player pause its playback and stay at its current 29924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * position. 30024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 30124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void pause(); 30224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 30324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 30424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Request that the player stop its playback; it may clear its state in 30524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * whatever way is appropriate. 30624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 30724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void stop(); 30824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 30924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 31024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Move to a new location in the media stream. 31124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 31224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param pos Position to move to, in milliseconds. 31324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 31424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void seekTo(long pos); 31524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 31624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 31724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start fast forwarding. If playback is already fast forwarding this 31824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * may increase the rate. 31924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 32024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void fastForward(); 32124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 32224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 32324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the next item. 32424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 32524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToNext(); 32624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 32724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 32824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Start rewinding. If playback is already rewinding this may increase 32924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the rate. 33024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 33124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void rewind(); 33224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 33324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 33424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Skip to the previous item. 33524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 33624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void skipToPrevious(); 33724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 33824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 33924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Rate the current content. This will cause the rating to be set for 34024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * the current user. The Rating type must match the type returned by 34124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * {@link #getRatingType()}. 34224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 34324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @param rating The rating to set for the current content 34424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 34524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public abstract void setRating(RatingCompat rating); 34624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 34724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 34824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 34924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Holds information about the way volume is handled for this session. 35024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 35124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class VolumeInfo { 35224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mVolumeType; 3531435afe32073dee10e721dfb6122ce6a194a6412RoboErik // TODO update audio stream with AudioAttributes support version 35424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mAudioStream; 35524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mVolumeControl; 35624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mMaxVolume; 35724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final int mCurrentVolume; 35824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 35924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown VolumeInfo(int type, int stream, int control, int max, int current) { 36024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mVolumeType = type; 36124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mAudioStream = stream; 36224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mVolumeControl = control; 36324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mMaxVolume = max; 36424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCurrentVolume = current; 36524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 36624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 36724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 36824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume handling, either local or remote. One of: 36924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 37024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link MediaSessionCompat#VOLUME_TYPE_LOCAL}</li> 37124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link MediaSessionCompat#VOLUME_TYPE_REMOTE}</li> 37224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 37324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 37424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume handling this session is using. 37524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 37624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getVolumeType() { 37724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mVolumeType; 37824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 38024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 38124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the stream this is currently controlling volume on. When the volume 38224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * type is {@link MediaSessionCompat#VOLUME_TYPE_REMOTE} this value does not 38324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * have meaning and should be ignored. 38424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 38524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The stream this session is playing on. 38624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 38724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getAudioStream() { 38824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mAudioStream; 38924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 39024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 39124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 39224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the type of volume control that can be used. One of: 39324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <ul> 39424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE}</li> 39524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_RELATIVE}</li> 39624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * <li>{@link VolumeProviderCompat#VOLUME_CONTROL_FIXED}</li> 39724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * </ul> 39824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 39924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The type of volume control that may be used with this 40024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * session. 40124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 40224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getVolumeControl() { 40324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mVolumeControl; 40424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 40524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 40624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 40724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the maximum volume that may be set for this session. 40824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 40924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The maximum allowed volume where this session is playing. 41024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 41124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getMaxVolume() { 41224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mMaxVolume; 41324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 41424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 41524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 41624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Get the current volume for this session. 41724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 41824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * @return The current volume where this session is playing. 41924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 42024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getCurrentVolume() { 42124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mCurrentVolume; 42224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 42324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 42424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 42524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown interface MediaControllerImpl { 42624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown void addCallback(Callback callback, Handler handler); 42724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown void removeCallback(Callback callback); 42824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown boolean dispatchMediaButtonEvent(KeyEvent keyEvent); 42924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown TransportControls getTransportControls(); 43024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown PlaybackStateCompat getPlaybackState(); 43124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaMetadataCompat getMetadata(); 43224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int getRatingType(); 43324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown VolumeInfo getVolumeInfo(); 434b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal void sendCommand(String command, Bundle params, ResultReceiver cb); 43524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object getMediaController(); 43624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 43724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 43824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // TODO: compatibility implementation 43924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplBase implements MediaControllerImpl { 44024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 44124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void addCallback(Callback callback, Handler handler) { 44224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 44424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 44524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void removeCallback(Callback callback) { 44624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 44824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 44924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 45024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return false; 45124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 45224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 45324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 45424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 45524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 45624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 45724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 45824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 45924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 46024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 46124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 46224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 46324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 46424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 46524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 46624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 46724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 46824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 46924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 47024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return 0; 47124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 47224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 47324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 47424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public VolumeInfo getVolumeInfo() { 47524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 47624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 47724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 47824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 479b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 48024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 48124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 48224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 48324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 48424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return null; 48524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 48624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 48724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 48824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class MediaControllerImplApi21 implements MediaControllerImpl { 48924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final Object mControllerObj; 49024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 49124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat session) { 4925c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 49324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown session.getSessionToken().getToken()); 49424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 49524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 49624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken) 49724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throws RemoteException { 49824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // TODO: refactor framework implementation 4995c41750574ba65da432b69f89cd32dc356281005RoboErik mControllerObj = MediaControllerCompatApi21.fromToken(context, 50024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown sessionToken.getToken()); 50124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mControllerObj == null) throw new RemoteException(); 50224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 50324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 50424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 50524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void addCallback(Callback callback, Handler handler) { 50624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.addCallback(mControllerObj, callback.mCallbackObj, handler); 50724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 50824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 50924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 51024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void removeCallback(Callback callback) { 51124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.removeCallback(mControllerObj, callback.mCallbackObj); 51224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 51324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 51424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 51524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public boolean dispatchMediaButtonEvent(KeyEvent event) { 51624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.dispatchMediaButtonEvent(mControllerObj, event); 51724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 51824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 51924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 52024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControls getTransportControls() { 5211435afe32073dee10e721dfb6122ce6a194a6412RoboErik Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj); 52224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return controlsObj != null ? new TransportControlsApi21(controlsObj) : null; 52324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 52424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 52524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 52624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public PlaybackStateCompat getPlaybackState() { 52724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object stateObj = MediaControllerCompatApi21.getPlaybackState(mControllerObj); 52824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return stateObj != null ? PlaybackStateCompat.fromPlaybackState(stateObj) : null; 52924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 53024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 53124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 53224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public MediaMetadataCompat getMetadata() { 53324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object metadataObj = MediaControllerCompatApi21.getMetadata(mControllerObj); 53424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return metadataObj != null ? MediaMetadataCompat.fromMediaMetadata(metadataObj) : null; 53524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 53624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 53724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 53824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public int getRatingType() { 53924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return MediaControllerCompatApi21.getRatingType(mControllerObj); 54024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 54124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 54224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 54324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public VolumeInfo getVolumeInfo() { 54424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Object volumeInfoObj = MediaControllerCompatApi21.getVolumeInfo(mControllerObj); 54524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return volumeInfoObj != null ? new VolumeInfo( 54624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.VolumeInfo.getVolumeType(volumeInfoObj), 5471435afe32073dee10e721dfb6122ce6a194a6412RoboErik MediaControllerCompatApi21.VolumeInfo.getLegacyAudioStream(volumeInfoObj), 54824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.VolumeInfo.getVolumeControl(volumeInfoObj), 54924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.VolumeInfo.getMaxVolume(volumeInfoObj), 55024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.VolumeInfo.getCurrentVolume(volumeInfoObj)) : null; 55124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 55224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 55324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 554b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal public void sendCommand(String command, Bundle params, ResultReceiver cb) { 555b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal MediaControllerCompatApi21.sendCommand(mControllerObj, command, params, cb); 55624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 55724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 55824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 55924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getMediaController() { 56024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mControllerObj; 56124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 56224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 56324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 56424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class TransportControlsApi21 extends TransportControls { 56524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private final Object mControlsObj; 56624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 56724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public TransportControlsApi21(Object controlsObj) { 56824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mControlsObj = controlsObj; 56924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 57024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 57124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 57224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void play() { 57324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.play(mControlsObj); 57424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 57524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 57624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 57724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void pause() { 57824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.pause(mControlsObj); 57924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 58024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 58124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 58224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void stop() { 58324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.stop(mControlsObj); 58424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 58524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 58624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 58724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void seekTo(long pos) { 58824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.seekTo(mControlsObj, pos); 58924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 59024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 59124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 59224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void fastForward() { 59324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.fastForward(mControlsObj); 59424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 59524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 59624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 59724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void rewind() { 59824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.rewind(mControlsObj); 59924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 60024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 60124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 60224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToNext() { 60324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToNext(mControlsObj); 60424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 60524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 60624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 60724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void skipToPrevious() { 60824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.skipToPrevious(mControlsObj); 60924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 61024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 61124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 61224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void setRating(RatingCompat rating) { 61324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaControllerCompatApi21.TransportControls.setRating(mControlsObj, 61424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown rating != null ? rating.getRating() : null); 61524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 61624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 61724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 618