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
1985d539daa11f9f7bd61ecb8ebb4d43536c02a736RoboErikimport android.app.PendingIntent;
2024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.content.Context;
2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.content.Intent;
221435afe32073dee10e721dfb6122ce6a194a6412RoboErikimport android.media.AudioAttributes;
23ceb8bf5e5cce7a37736981e626c4be416378767bRoboErikimport android.media.MediaDescription;
2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.media.MediaMetadata;
2524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.media.Rating;
2624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.media.VolumeProvider;
2724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.media.session.MediaSession;
2824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.media.session.PlaybackState;
2924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Bundle;
3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Handler;
3124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Parcelable;
3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.ResultReceiver;
33be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsooimport android.util.Log;
3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
3589febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport androidx.annotation.RequiresApi;
3689febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikas
37be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsooimport java.lang.reflect.Field;
38ceb8bf5e5cce7a37736981e626c4be416378767bRoboErikimport java.util.ArrayList;
39ceb8bf5e5cce7a37736981e626c4be416378767bRoboErikimport java.util.List;
40ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
418f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette@RequiresApi(21)
4224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownclass MediaSessionCompatApi21 {
43be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo    static final String TAG = "MediaSessionCompatApi21";
44be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo
4524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static Object createSession(Context context, String tag) {
46f87e8513ce55303168acd9c698acd5bbd33b9badRoboErik        return new MediaSession(context, tag);
4724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
4824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
49bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik    public static Object verifySession(Object mediaSession) {
50bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik        if (mediaSession instanceof MediaSession) {
51bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik            return mediaSession;
52bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik        }
53bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik        throw new IllegalArgumentException("mediaSession is not a valid MediaSession object");
54bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik    }
55bbcdf78e350d58ecd6baa75e282d4908d3129fe2RoboErik
56ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik    public static Object verifyToken(Object token) {
57ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik        if (token instanceof MediaSession.Token) {
58ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik            return token;
59ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik        }
60ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik        throw new IllegalArgumentException("token is not a valid MediaSession.Token object");
61ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik    }
62ae70d8d953ef632acb9f176609a1f75bd948d101RoboErik
6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static Object createCallback(Callback callback) {
6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return new CallbackProxy<Callback>(callback);
6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
678af0092e2d7409e79779af396d63ca4146f1fb21RoboErik    public static void setCallback(Object sessionObj, Object callbackObj, Handler handler) {
688af0092e2d7409e79779af396d63ca4146f1fb21RoboErik        ((MediaSession) sessionObj).setCallback((MediaSession.Callback) callbackObj, handler);
6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setFlags(Object sessionObj, int flags) {
7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).setFlags(flags);
7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setPlaybackToLocal(Object sessionObj, int stream) {
761435afe32073dee10e721dfb6122ce6a194a6412RoboErik        // TODO update APIs to use support version of AudioAttributes
771435afe32073dee10e721dfb6122ce6a194a6412RoboErik        AudioAttributes.Builder bob = new AudioAttributes.Builder();
781435afe32073dee10e721dfb6122ce6a194a6412RoboErik        bob.setLegacyStreamType(stream);
791435afe32073dee10e721dfb6122ce6a194a6412RoboErik        ((MediaSession) sessionObj).setPlaybackToLocal(bob.build());
8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setPlaybackToRemote(Object sessionObj, Object volumeProviderObj) {
8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).setPlaybackToRemote((VolumeProvider)volumeProviderObj);
8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setActive(Object sessionObj, boolean active) {
8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).setActive(active);
8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static boolean isActive(Object sessionObj) {
9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return ((MediaSession)sessionObj).isActive();
9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
9324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void sendSessionEvent(Object sessionObj, String event, Bundle extras) {
9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).sendSessionEvent(event, extras);
9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void release(Object sessionObj) {
9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).release();
10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static Parcelable getSessionToken(Object sessionObj) {
10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return ((MediaSession)sessionObj).getSessionToken();
10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setPlaybackState(Object sessionObj, Object stateObj) {
10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).setPlaybackState((PlaybackState)stateObj);
10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static void setMetadata(Object sessionObj, Object metadataObj) {
11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ((MediaSession)sessionObj).setMetadata((MediaMetadata)metadataObj);
11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
11485d539daa11f9f7bd61ecb8ebb4d43536c02a736RoboErik    public static void setSessionActivity(Object sessionObj, PendingIntent pi) {
11585d539daa11f9f7bd61ecb8ebb4d43536c02a736RoboErik        ((MediaSession) sessionObj).setSessionActivity(pi);
11685d539daa11f9f7bd61ecb8ebb4d43536c02a736RoboErik    }
11785d539daa11f9f7bd61ecb8ebb4d43536c02a736RoboErik
118ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    public static void setMediaButtonReceiver(Object sessionObj, PendingIntent pi) {
119ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        ((MediaSession) sessionObj).setMediaButtonReceiver(pi);
120ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    }
121ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
122ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    public static void setQueue(Object sessionObj, List<Object> queueObjs) {
123ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        if (queueObjs == null) {
124ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            ((MediaSession) sessionObj).setQueue(null);
125ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            return;
126ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        }
127ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        ArrayList<MediaSession.QueueItem> queue = new ArrayList<MediaSession.QueueItem>();
128ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        for (Object itemObj : queueObjs) {
129ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            queue.add((MediaSession.QueueItem) itemObj);
130ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        }
131ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        ((MediaSession) sessionObj).setQueue(queue);
132ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    }
133ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
134ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    public static void setQueueTitle(Object sessionObj, CharSequence title) {
135ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        ((MediaSession) sessionObj).setQueueTitle(title);
136ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    }
137ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
138ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    public static void setExtras(Object sessionObj, Bundle extras) {
139ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        ((MediaSession) sessionObj).setExtras(extras);
140ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    }
141ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
142be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo    public static boolean hasCallback(Object sessionObj) {
143be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo        Field callbackField = null;
144be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo        try {
1451659cb18a7a8efcfe29b4fa1bac4e6e1344af49cSungsoo Lim            callbackField = sessionObj.getClass().getDeclaredField("mCallback");
146be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo            if (callbackField != null) {
147be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo                callbackField.setAccessible(true);
148be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo                return callbackField.get(sessionObj) != null;
149be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo            }
150be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo        } catch (NoSuchFieldException | IllegalAccessException e) {
151be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo            Log.w(TAG, "Failed to get mCallback object.");
152be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo        }
153be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo        return false;
154be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo    }
155be3bec76ad7ad0248c35549a89e2a3cf27348f65Sungsoo
156bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake    interface Callback {
157bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onCommand(String command, Bundle extras, ResultReceiver cb);
158bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        boolean onMediaButtonEvent(Intent mediaButtonIntent);
159bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onPlay();
160bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onPlayFromMediaId(String mediaId, Bundle extras);
161bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onPlayFromSearch(String search, Bundle extras);
162bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onSkipToQueueItem(long id);
163bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onPause();
164bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onSkipToNext();
165bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onSkipToPrevious();
166bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onFastForward();
167bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onRewind();
168bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onStop();
169bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onSeekTo(long position);
170bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onSetRating(Object ratingObject);
171d4265a9bec0d7bb3e012613dd2de841f392d5f88yangren        void onSetRating(Object ratingObject, Bundle extras);
172bd51c368d8bf32d652ae370c2723080d82b2834dIan Lake        void onCustomAction(String action, Bundle extras);
17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    static class CallbackProxy<T extends Callback> extends MediaSession.Callback {
17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        protected final T mCallback;
17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public CallbackProxy(T callback) {
17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback = callback;
18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
183b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal        public void onCommand(String command, Bundle args, ResultReceiver cb) {
184b530c89bba371d2d575f10480b2e90914b0d3f3fGabriel Peal            mCallback.onCommand(command, args, cb);
18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
1878af0092e2d7409e79779af396d63ca4146f1fb21RoboErik        @Override
1888af0092e2d7409e79779af396d63ca4146f1fb21RoboErik        public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
189944a4e92d6d9619fa1a2172a4ec9dc683eb65b40Ian Lake            return mCallback.onMediaButtonEvent(mediaButtonIntent)
190944a4e92d6d9619fa1a2172a4ec9dc683eb65b40Ian Lake                    || super.onMediaButtonEvent(mediaButtonIntent);
19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
19224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
19424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onPlay() {
19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onPlay();
19624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
19926d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        public void onPlayFromMediaId(String mediaId, Bundle extras) {
20026d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake            mCallback.onPlayFromMediaId(mediaId, extras);
20126d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        }
20226d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake
20326d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        @Override
20426d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        public void onPlayFromSearch(String search, Bundle extras) {
20526d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake            mCallback.onPlayFromSearch(search, extras);
20626d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        }
20726d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake
20826d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        @Override
20926d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        public void onSkipToQueueItem(long id) {
21026d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake            mCallback.onSkipToQueueItem(id);
21126d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        }
21226d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake
21326d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        @Override
21424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onPause() {
21524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onPause();
21624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
21724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
21824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
21924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onSkipToNext() {
22024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onSkipToNext();
22124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
22224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
22424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onSkipToPrevious() {
22524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onSkipToPrevious();
22624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
22724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
22924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onFastForward() {
23024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onFastForward();
23124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
23224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
23324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
23424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onRewind() {
23524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onRewind();
23624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
23724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
23824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
23924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onStop() {
24024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onStop();
24124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
24224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
24424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onSeekTo(long pos) {
24524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onSeekTo(pos);
24624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
24724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
24924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public void onSetRating(Rating rating) {
25024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mCallback.onSetRating(rating);
25124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
25226d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake
25326d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        @Override
25426d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        public void onCustomAction(String action, Bundle extras) {
25526d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake            mCallback.onCustomAction(action, extras);
25626d994357fa4dbcd813f1c066ce09d5fdaa301a9Ian Lake        }
25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
258ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
259ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    static class QueueItem {
260ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
261ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        public static Object createItem(Object mediaDescription, long id) {
262ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            return new MediaSession.QueueItem((MediaDescription) mediaDescription, id);
263ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        }
264ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
265ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        public static Object getDescription(Object queueItem) {
266ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            return ((MediaSession.QueueItem) queueItem).getDescription();
267ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        }
268ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik
269ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        public static long getQueueId(Object queueItem) {
270ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik            return ((MediaSession.QueueItem) queueItem).getQueueId();
271ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik        }
2720f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton
2730f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton        private QueueItem() {
2740f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton        }
2750f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton    }
2760f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton
2770f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton    private MediaSessionCompatApi21() {
278ceb8bf5e5cce7a37736981e626c4be416378767bRoboErik    }
27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
280