1fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang/*
2fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Copyright 2018 The Android Open Source Project
3fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *
4fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Licensed under the Apache License, Version 2.0 (the "License");
5fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * you may not use this file except in compliance with the License.
6fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * You may obtain a copy of the License at
7fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *
8fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *      http://www.apache.org/licenses/LICENSE-2.0
9fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *
10fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Unless required by applicable law or agreed to in writing, software
11fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * distributed under the License is distributed on an "AS IS" BASIS,
12fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * See the License for the specific language governing permissions and
14fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * limitations under the License.
15fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang */
16fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
17fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangpackage androidx.media;
18fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
19fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
21fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.annotation.TargetApi;
22fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.app.PendingIntent;
23fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.Context;
24fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.Intent;
25fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.AudioFocusRequest;
26fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.net.Uri;
27fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Build;
28fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Bundle;
29fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.IBinder;
302b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Limimport android.os.RemoteException;
31fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.ResultReceiver;
321df65e9a40c933daca477b2c9d1d28389fa66aecHyundo Moonimport android.support.v4.media.session.MediaSessionCompat;
33fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.v4.media.session.PlaybackStateCompat;
34fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
35fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.IntDef;
36fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.NonNull;
37fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.Nullable;
38fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.RestrictTo;
39f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moonimport androidx.media.MediaController2.PlaybackInfo;
404c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kangimport androidx.media.MediaPlayerInterface.BuffState;
414c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kangimport androidx.media.MediaPlayerInterface.PlayerState;
42fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaPlaylistAgent.PlaylistEventCallback;
43fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaPlaylistAgent.RepeatMode;
44fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaPlaylistAgent.ShuffleMode;
45fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
46fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.lang.annotation.Retention;
47fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.lang.annotation.RetentionPolicy;
48fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.List;
49fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.Executor;
50fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
51fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang/**
52fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Allows a media app to expose its transport controls and playback information in a process to
53fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * other processes including the Android framework and other apps. Common use cases are as follows.
54fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <ul>
55fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *     <li>Bluetooth/wired headset key events support</li>
56fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *     <li>Android Auto/Wearable support</li>
57fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang *     <li>Separating UI process and playback process</li>
58fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * </ul>
59fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <p>
60fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * A MediaSession2 should be created when an app wants to publish media playback information or
61fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * handle media keys. In general an app only needs one session for all playback, though multiple
62fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * sessions can be created to provide finer grain controls of media.
63fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <p>
64917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim * If you want to support background playback, {@link MediaSessionService2} is preferred
65917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim * instead. With it, your playback can be revived even after playback is finished. See
66917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim * {@link MediaSessionService2} for details.
67917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim * <p>
68fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * A session can be obtained by {@link Builder}. The owner of the session may pass its session token
69fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * to other processes to allow them to create a {@link MediaController2} to interact with the
70fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * session.
71fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <p>
72fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * When a session receive transport control commands, the session sends the commands directly to
73fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * the the underlying media player set by {@link Builder} or
74fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * {@link #updatePlayer}.
75fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <p>
76fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * When an app is finished performing playback it must call {@link #close()} to clean up the session
77fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * and notify any controllers.
78fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * <p>
79fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * {@link MediaSession2} objects should be used on the thread on the looper.
80917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim *
81917d3a3d64b619a8e3925e0fcb8659eaab7bfaaeJaewan Kim * @see MediaSessionService2
82fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang */
83fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@TargetApi(Build.VERSION_CODES.KITKAT)
84fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangpublic class MediaSession2 extends MediaInterface2.SessionPlayer implements AutoCloseable {
85fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
86fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * @hide
87fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
88fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @RestrictTo(LIBRARY_GROUP)
89fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @IntDef({ERROR_CODE_UNKNOWN_ERROR, ERROR_CODE_APP_ERROR, ERROR_CODE_NOT_SUPPORTED,
90fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            ERROR_CODE_AUTHENTICATION_EXPIRED, ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED,
91fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            ERROR_CODE_CONCURRENT_STREAM_LIMIT, ERROR_CODE_PARENTAL_CONTROL_RESTRICTED,
92fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            ERROR_CODE_NOT_AVAILABLE_IN_REGION, ERROR_CODE_CONTENT_ALREADY_PLAYING,
93fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            ERROR_CODE_SKIP_LIMIT_REACHED, ERROR_CODE_ACTION_ABORTED, ERROR_CODE_END_OF_QUEUE,
94fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            ERROR_CODE_SETUP_REQUIRED})
95fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Retention(RetentionPolicy.SOURCE)
96fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public @interface ErrorCode {}
97fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
98fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
99fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * This is the default error code and indicates that none of the other error codes applies.
100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_UNKNOWN_ERROR = 0;
102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the application state is invalid to fulfill the request.
105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_APP_ERROR = 1;
107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the request is not supported by the application.
110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_NOT_SUPPORTED = 2;
112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the request cannot be performed because authentication has expired.
115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3;
117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when a premium account is required for the request to succeed.
120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4;
122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when too many concurrent streams are detected.
125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5;
127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the content is blocked due to parental controls.
130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6;
132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the content is blocked due to being regionally unavailable.
135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7;
137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the requested content is already playing.
140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8;
142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the application cannot skip any more songs because skip limit is reached.
145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9;
147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the action is interrupted due to some external event.
150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
151fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_ACTION_ABORTED = 10;
152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the playback navigation (previous, next) is not possible because the queue
155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * was exhausted.
156fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
157fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_END_OF_QUEUE = 11;
158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Error code when the session needs user's manual intervention.
161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public static final int ERROR_CODE_SETUP_REQUIRED = 12;
163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
164d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    static final String TAG = "MediaSession2";
165d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
166d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    private final SupportLibraryImpl mImpl;
167d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
168d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    MediaSession2(SupportLibraryImpl impl) {
169d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl = impl;
170d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
171d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
172d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    SupportLibraryImpl getImpl() {
173d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl;
174d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
175d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
176fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
177d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets the underlying {@link MediaPlayerInterface} and {@link MediaPlaylistAgent} for this
178d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * session to dispatch incoming event to.
179d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
180d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * When a {@link MediaPlaylistAgent} is specified here, the playlist agent should manage
181d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaPlayerInterface} for calling
182d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaPlayerInterface#setNextDataSources(List)}.
183d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
184d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * If the {@link MediaPlaylistAgent} isn't set, session will recreate the default playlist
185d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * agent.
186fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     *
187d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param player a {@link MediaPlayerInterface} that handles actual media playback in your app
188d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the {@code player}
189d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param volumeProvider a {@link VolumeProviderCompat}. If {@code null}, system will adjust the
190d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *                       appropriate stream volume for this session's player.
191fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
192d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void updatePlayer(@NonNull MediaPlayerInterface player,
193d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @Nullable MediaPlaylistAgent playlistAgent,
194d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @Nullable VolumeProviderCompat volumeProvider) {
195d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.updatePlayer(player, playlistAgent, volumeProvider);
196d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
197d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
198d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
199d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void close() {
200d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        try {
201d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mImpl.close();
202d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        } catch (Exception e) {
203d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            // Should not be here.
204d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
205fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
206fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
207fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
208d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return player
209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
210d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @NonNull MediaPlayerInterface getPlayer() {
211d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlayer();
212d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
213fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
214d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
215d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return playlist agent
216d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
217d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @NonNull MediaPlaylistAgent getPlaylistAgent() {
218d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlaylistAgent();
219d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
221d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
222d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return volume provider
223d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
224d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @Nullable VolumeProviderCompat getVolumeProvider() {
225d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getVolumeProvider();
226d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
227fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
228d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
229d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Returns the {@link SessionToken2} for creating {@link MediaController2}.
230d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
231d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @NonNull SessionToken2 getToken() {
232d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getToken();
233d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
234fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
235d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @NonNull Context getContext() {
236d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getContext();
237d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
239d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @NonNull Executor getCallbackExecutor() {
240d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getCallbackExecutor();
241d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
242fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
243d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @NonNull SessionCallback getCallback() {
244d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getCallback();
245d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
247d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
248d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Returns the list of connected controller.
249d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
250d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return list of {@link ControllerInfo}
251d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
252d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @NonNull List<ControllerInfo> getConnectedControllers() {
253d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getConnectedControllers();
254d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
256d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
257d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Set the {@link AudioFocusRequest} to obtain the audio focus
258d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
259d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param afr the full request parameters
260d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
261d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setAudioFocusRequest(@Nullable AudioFocusRequest afr) {
262d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setAudioFocusRequest(afr);
263d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
264fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
265d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
266d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets ordered list of {@link CommandButton} for controllers to build UI with it.
267d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
268d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * It's up to controller's decision how to represent the layout in its own UI.
269d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Here's the same way
270d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * (layout[i] means a CommandButton at index i in the given list)
271d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * For 5 icons row
272d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      layout[3] layout[1] layout[0] layout[2] layout[4]
273d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * For 3 icons row
274d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      layout[1] layout[0] layout[2]
275d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * For 5 icons row with overflow icon (can show +5 extra buttons with overflow button)
276d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      expanded row:   layout[5] layout[6] layout[7] layout[8] layout[9]
277d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      main row:       layout[3] layout[1] layout[0] layout[2] layout[4]
278d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
279d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This API can be called in the
280d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link SessionCallback#onConnect(MediaSession2, ControllerInfo)}.
281d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
282d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param controller controller to specify layout.
283d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param layout ordered list of layout.
284d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
285d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setCustomLayout(@NonNull ControllerInfo controller,
286d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @NonNull List<CommandButton> layout) {
287d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setCustomLayout(controller, layout);
288d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
290d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
291d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Set the new allowed command group for the controller
292d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
293d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param controller controller to change allowed commands
294d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param commands new allowed commands
295d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
296d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setAllowedCommands(@NonNull ControllerInfo controller,
297d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @NonNull SessionCommandGroup2 commands) {
298d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setAllowedCommands(controller, commands);
299d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
301d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
302d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Send custom command to all connected controllers.
303d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
304d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param command a command
305d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param args optional argument
306d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
307d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args) {
308d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.sendCustomCommand(command, args);
309d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
311d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
312d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Send custom command to a specific controller.
313d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
314d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param command a command
315d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param args optional argument
316d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param receiver result receiver for the session
317d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
318d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void sendCustomCommand(@NonNull ControllerInfo controller,
319d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @NonNull SessionCommand2 command, @Nullable Bundle args,
320d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @Nullable ResultReceiver receiver) {
321d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.sendCustomCommand(controller, command, args, receiver);
322d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
323fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
324d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
325d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Play playback.
326d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
327d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlayerInterface#play()}.
328d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
329d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
330d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void play() {
331d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.play();
332d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
333fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim
334d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
335d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Pause playback.
336d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
337d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlayerInterface#pause()}.
338d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
339d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
340d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void pause() {
341d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.pause();
342d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
343fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim
344d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
345d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Stop playback, and reset the player to the initial state.
346d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
347d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlayerInterface#reset()}.
348d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
349d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
350d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void reset() {
351d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.reset();
352d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
353fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
354d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
355d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Request that the player prepare its playback. In other words, other sessions can continue
356d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * to play during the preparation of this session. This method can be used to speed up the
357d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * start of the playback. Once the preparation is done, the session will change its playback
358d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * state to {@link MediaPlayerInterface#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be
359d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * called to start playback.
360d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
361d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlayerInterface#reset()}.
362d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
363d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
364d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void prepare() {
365d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.prepare();
366d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
367fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
368d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
369d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Move to a new location in the media stream.
370d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
371d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param pos Position to move to, in milliseconds.
372d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
373d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
374d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void seekTo(long pos) {
375d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.seekTo(pos);
376d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
377fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
378d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
379d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @hide
380d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
381d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @RestrictTo(LIBRARY_GROUP)
382d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
383d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void skipForward() {
384d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.skipForward();
385d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
386fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
387d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
388d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @hide
389d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
390d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @RestrictTo(LIBRARY_GROUP)
391d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
392d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void skipBackward() {
393d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.skipBackward();
394d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
395fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
396d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
397d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Notify errors to the connected controllers
398d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
399d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param errorCode error code
400d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param extras extras
401d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
402d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
403d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) {
404d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.notifyError(errorCode, extras);
405d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
406fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
407d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
408d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Notify routes information to a connected controller
409d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
410d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param controller controller information
411d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param routes The routes information. Each bundle should be from
412d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *              MediaRouteDescritor.asBundle().
413d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
414d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
415d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            @Nullable List<Bundle> routes) {
416d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.notifyRoutesInfoChanged(controller, routes);
417d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
418d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
419d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
420d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the current player state.
421d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
422d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the current player state
423d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
424d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
425d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @PlayerState int getPlayerState() {
426d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlayerState();
427d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
428d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
429d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
430d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the current position.
431d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
432d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the current playback position in ms, or {@link MediaPlayerInterface#UNKNOWN_TIME} if
433d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *         unknown.
434d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
435d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
436d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public long getCurrentPosition() {
437d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getCurrentPosition();
438d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
439d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
440d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
441d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the duration of the currently playing media item.
442d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
443d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the duration of the current item from {@link MediaPlayerInterface#getDuration()}.
444d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
445d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
446d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public long getDuration() {
447d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getDuration();
448d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
449d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
450d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
451d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the buffered position, or {@link MediaPlayerInterface#UNKNOWN_TIME} if unknown.
452d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
453d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the buffered position in ms, or {@link MediaPlayerInterface#UNKNOWN_TIME}.
454d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
455d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
456d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public long getBufferedPosition() {
457d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getBufferedPosition();
458d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
460d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
461d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the current buffering state of the player.
462d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
463d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * buffered.
464d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
465d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the buffering state.
466d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
467d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
468d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @BuffState int getBufferingState() {
469d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getBufferingState();
470d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
471fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
472d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
473d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Get the playback speed.
474d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
475d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return speed
476d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
477d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
478d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public float getPlaybackSpeed() {
479d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlaybackSpeed();
480d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
482d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
483d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Set the playback speed.
484d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
485d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
486d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setPlaybackSpeed(float speed) {
487d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setPlaybackSpeed(speed);
488fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
489fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
490fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
491d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets the data source missing helper. Helper will be used to provide default implementation of
492d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaPlaylistAgent} when it isn't set by developer.
493fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
494d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Default implementation of the {@link MediaPlaylistAgent} will call helper when a
495d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaItem2} in the playlist doesn't have a {@link DataSourceDesc}. This may happen
496d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * when
497d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <ul>
498d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      <li>{@link MediaItem2} specified by {@link #setPlaylist(List, MediaMetadata2)} doesn't
499d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          have {@link DataSourceDesc}</li>
500d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      <li>{@link MediaController2#addPlaylistItem(int, MediaItem2)} is called and accepted
501d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          by {@link SessionCallback#onCommandRequest(
502d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          MediaSession2, ControllerInfo, SessionCommand2)}.
503d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          In that case, an item would be added automatically without the data source.</li>
504d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * </ul>
505fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
506d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * If it's not set, playback wouldn't happen for the item without data source descriptor.
507d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
508d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * The helper will be run on the executor that was specified by
509d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link Builder#setSessionCallback(Executor, SessionCallback)}.
510d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
511d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param helper a data source missing helper.
512d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @throws IllegalStateException when the helper is set when the playlist agent is set
513d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #setPlaylist(List, MediaMetadata2)
514d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)
515d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM
516d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REPLACE_ITEM
517fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
518d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
519d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setOnDataSourceMissingHelper(@NonNull OnDataSourceMissingHelper helper) {
520d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setOnDataSourceMissingHelper(helper);
521d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
522fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
523d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
524d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Clears the data source missing helper.
525d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
526d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #setOnDataSourceMissingHelper(OnDataSourceMissingHelper)
527d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
528d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
529d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void clearOnDataSourceMissingHelper() {
530d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.clearOnDataSourceMissingHelper();
531d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
532fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
533d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
534d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Returns the playlist from the {@link MediaPlaylistAgent}.
535d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
536d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This list may differ with the list that was specified with
537d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent}
538d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * implementation. Use media items returned here for other playlist agent APIs such as
539d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}.
540d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
541d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return playlist
542d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#getPlaylist()
543d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see SessionCallback#onPlaylistChanged(
544d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
545d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
546d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
547d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public List<MediaItem2> getPlaylist() {
548d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlaylist();
549d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
550fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
551d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
552d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets a list of {@link MediaItem2} to the {@link MediaPlaylistAgent}. Ensure uniqueness of
553d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * each {@link MediaItem2} in the playlist so the session can uniquely identity individual
554d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * items.
555d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
556d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This may be an asynchronous call, and {@link MediaPlaylistAgent} may keep the copy of the
557d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * list. Wait for {@link SessionCallback#onPlaylistChanged(MediaSession2, MediaPlaylistAgent,
558d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * List, MediaMetadata2)} to know the operation finishes.
559d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
560d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * You may specify a {@link MediaItem2} without {@link DataSourceDesc}. In that case,
561d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaPlaylistAgent} has responsibility to dynamically query {link DataSourceDesc}
562d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * when such media item is ready for preparation or play. Default implementation needs
563d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link OnDataSourceMissingHelper} for such case.
564d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
565d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * It's recommended to fill {@link MediaMetadata2} in each {@link MediaItem2} especially for the
566d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * duration information with the key {@link MediaMetadata2#METADATA_KEY_DURATION}. Without the
567d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * duration information in the metadata, session will do extra work to get the duration and send
568d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * it to the controller.
569d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
570d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param list A list of {@link MediaItem2} objects to set as a play list.
571d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @throws IllegalArgumentException if given list is {@code null}, or has duplicated media
572d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * items.
573d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#setPlaylist(List, MediaMetadata2)
574d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see SessionCallback#onPlaylistChanged(
575d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *          MediaSession2, MediaPlaylistAgent, List, MediaMetadata2)
576d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #setOnDataSourceMissingHelper
577d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
578d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
579d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
580d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setPlaylist(list, metadata);
581d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
582fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
583d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
584d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Skips to the item in the playlist.
585d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
586d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)} and the behavior depends
587d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * on the playlist agent implementation, especially with the shuffle/repeat mode.
588d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
589d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param item The item in the playlist you want to play
590d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getShuffleMode()
591d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getRepeatMode()
592d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
593d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
594d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void skipToPlaylistItem(@NonNull MediaItem2 item) {
595d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.skipToPlaylistItem(item);
596d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
597fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
598d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
599d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Skips to the previous item.
600d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
601d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlaylistAgent#skipToPreviousItem()} and the behavior depends on the
602d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * playlist agent implementation, especially with the shuffle/repeat mode.
603d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
604d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getShuffleMode()
605d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getRepeatMode()
606d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     **/
607d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
608d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void skipToPreviousItem() {
609d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.skipToPreviousItem();
610d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
611fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
612d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
613d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Skips to the next item.
614d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
615d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This calls {@link MediaPlaylistAgent#skipToNextItem()} and the behavior depends on the
616d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * playlist agent implementation, especially with the shuffle/repeat mode.
617d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
618d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getShuffleMode()
619d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see #getRepeatMode()
620d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
621d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
622d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void skipToNextItem() {
623d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.skipToNextItem();
624fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
625fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
626fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
627d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the playlist metadata from the {@link MediaPlaylistAgent}.
628d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
629d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return the playlist metadata
630d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
631d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
632d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public MediaMetadata2 getPlaylistMetadata() {
633d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getPlaylistMetadata();
634d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
635d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
636d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
637d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Adds the media item to the playlist at position index. Index equals or greater than
638d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * the current playlist size (e.g. {@link Integer#MAX_VALUE}) will add the item at the end of
639d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * the playlist.
640fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
641d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This will not change the currently playing media item.
642d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * If index is less than or equal to the current index of the play list,
643d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * the current index of the play list will be incremented correspondingly.
644d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
645d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param index the index you want to add
646d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param item the media item you want to add
647fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
648d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
649d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
650d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.addPlaylistItem(index, item);
651d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
652fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
653d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
654d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Removes the media item in the playlist.
655d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
656d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * If the item is the currently playing item of the playlist, current playback
657d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * will be stopped and playback moves to next source in the list.
658d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
659d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param item the media item you want to add
660d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
661d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
662d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void removePlaylistItem(@NonNull MediaItem2 item) {
663d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.removePlaylistItem(item);
664d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
665fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
666d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
667d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Replaces the media item at index in the playlist. This can be also used to update metadata of
668d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * an item.
669d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
670d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param index the index of the item to replace
671d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param item the new item
672d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
673d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
674d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
675d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.replacePlaylistItem(index, item);
676d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
677fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
678d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
679d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Return currently playing media item.
680d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
681d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return currently playing media item
682d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
683d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
684d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public MediaItem2 getCurrentMediaItem() {
685d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getCurrentMediaItem();
686d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
687fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
688d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
689d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Updates the playlist metadata to the {@link MediaPlaylistAgent}.
690d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
691d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param metadata metadata of the playlist
692d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
693d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
694d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
695d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.updatePlaylistMetadata(metadata);
696d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
697fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
698d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
699d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the repeat mode from the {@link MediaPlaylistAgent}.
700d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
701d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return repeat mode
702d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_NONE
703d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_ONE
704d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_ALL
705d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
706d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
707d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
708d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @RepeatMode int getRepeatMode() {
709d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getRepeatMode();
710d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
711fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
712d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
713d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets the repeat mode to the {@link MediaPlaylistAgent}.
714d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
715d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param repeatMode repeat mode
716d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_NONE
717d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_ONE
718d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_ALL
719d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
720d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
721d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
722d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setRepeatMode(@RepeatMode int repeatMode) {
723d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setRepeatMode(repeatMode);
724d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
725fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
726d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
727d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Gets the shuffle mode from the {@link MediaPlaylistAgent}.
728d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
729d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @return The shuffle mode
730d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
731d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
732d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
733d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
734d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
735d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public @ShuffleMode int getShuffleMode() {
736d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        return mImpl.getShuffleMode();
737d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
738fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
739d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
740d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Sets the shuffle mode to the {@link MediaPlaylistAgent}.
741d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
742d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @param shuffleMode The shuffle mode
743d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
744d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
745d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
746d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
747d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @Override
748d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public void setShuffleMode(@ShuffleMode int shuffleMode) {
749d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        mImpl.setShuffleMode(shuffleMode);
750fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
751fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
752fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
753d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Interface definition of a callback to be invoked when a {@link MediaItem2} in the playlist
754d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * didn't have a {@link DataSourceDesc} but it's needed now for preparing or playing it.
755d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *
756d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * #see #setOnDataSourceMissingHelper
757fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
758d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public interface OnDataSourceMissingHelper {
759d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
760d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a {@link MediaItem2} in the playlist didn't have a {@link DataSourceDesc}
761d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * but it's needed now for preparing or playing it. Returned data source descriptor will be
762d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * sent to the player directly to prepare or play the contents.
763d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
764d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * An exception may be thrown if the returned {@link DataSourceDesc} is duplicated in the
765d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * playlist, so items cannot be differentiated.
766d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
767d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
768d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param item media item from the controller
769d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return a data source descriptor if the media item. Can be {@code null} if the content
770d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *        isn't available.
771d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
772d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Nullable DataSourceDesc onDataSourceMissing(@NonNull MediaSession2 session,
773d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaItem2 item);
774d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    }
775fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
776d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    /**
777d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Callback to be called for all incoming commands from {@link MediaController2}s.
778d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
779d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * If it's not set, the session will accept all controllers and all incoming commands by
780d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * default.
781d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     */
782d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public abstract static class SessionCallback {
783fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
784d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller is created for this session. Return allowed commands for
785d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * controller. By default it allows all connection requests and commands.
786d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
787d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * You can reject the connection by return {@code null}. In that case, controller receives
788d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)} and cannot
789d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * be usable.
790d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
791d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
792d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information.
793d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return allowed commands. Can be {@code null} to reject connection.
794fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
795d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @Nullable SessionCommandGroup2 onConnect(@NonNull MediaSession2 session,
796d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller) {
797d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            SessionCommandGroup2 commands = new SessionCommandGroup2();
798d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            commands.addAllPredefinedCommands();
799d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return commands;
800fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
801fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
802fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
803d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller is disconnected
804d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
805d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
806d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
807fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
808d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onDisconnected(@NonNull MediaSession2 session,
809d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller) { }
810fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
811fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
812d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller sent a command which will be sent directly to one of the
813d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * following:
814d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <ul>
815d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *  <li> {@link MediaPlayerInterface} </li>
816d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *  <li> {@link MediaPlaylistAgent} </li>
817d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *  <li> {@link android.media.AudioManager} or {@link VolumeProviderCompat} </li>
818d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * </ul>
819d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Return {@code false} here to reject the request and stop sending command.
820d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
821d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
822d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information.
823d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param command a command. This method will be called for every single command.
824d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return {@code true} if you want to accept incoming command. {@code false} otherwise.
825d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PLAY
826d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PAUSE
827d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYBACK_RESET
828d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM
829d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM
830d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PREPARE
831d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYBACK_SEEK_TO
832d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM
833d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE
834d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE
835d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM
836d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REMOVE_ITEM
837d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REPLACE_ITEM
838d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST
839d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SET_LIST
840d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST_METADATA
841d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SET_LIST_METADATA
842d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_VOLUME_SET_VOLUME
843d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_VOLUME_ADJUST_VOLUME
844fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
845d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public boolean onCommandRequest(@NonNull MediaSession2 session,
846d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull SessionCommand2 command) {
847d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return true;
848fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
849fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
850fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
851d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller set rating of a media item through
852d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#setRating(String, Rating2)}.
853d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
854d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * To allow setting user rating for a {@link MediaItem2}, the media item's metadata
855d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * should have {@link Rating2} with the key {@link MediaMetadata2#METADATA_KEY_USER_RATING},
856d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * in order to provide possible rating style for controller. Controller will follow the
857d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * rating style.
858fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
859d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
860d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
861d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param mediaId media id from the controller
862d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param rating new rating from the controller
863d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_SET_RATING
864fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
865d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onSetRating(@NonNull MediaSession2 session, @NonNull ControllerInfo controller,
866d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull String mediaId, @NonNull Rating2 rating) { }
867fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
868d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
869d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller sent a custom command through
870d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#sendCustomCommand(SessionCommand2, Bundle, ResultReceiver)}.
871d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
872d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
873d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
874d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param customCommand custom command.
875d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param args optional arguments
876d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param cb optional result receiver
877d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_CUSTOM
878d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
879d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onCustomCommand(@NonNull MediaSession2 session,
880d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull SessionCommand2 customCommand,
881d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle args, @Nullable ResultReceiver cb) { }
882fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
883d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
884d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to play a specific mediaId through
885d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#playFromMediaId(String, Bundle)}.
886d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
887d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
888d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
889d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param mediaId media id
890d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
891d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID
892d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
893d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlayFromMediaId(@NonNull MediaSession2 session,
894d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull String mediaId,
895d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle extras) { }
896fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
897d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
898d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to begin playback from a search query through
899d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#playFromSearch(String, Bundle)}
900d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
901d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * An empty query indicates that the app may play any music. The implementation should
902d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * attempt to make a smart choice about what to play.
903d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
904d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
905d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
906d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param query query string. Can be empty to indicate any suggested media
907d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
908d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_SEARCH
909d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
910d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlayFromSearch(@NonNull MediaSession2 session,
911d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull String query,
912d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle extras) { }
913fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
914d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
915d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to play a specific media item represented by a URI
916d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * through {@link MediaController2#playFromUri(Uri, Bundle)}
917d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
918d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
919d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
920d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param uri uri
921d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
922d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_URI
923d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
924d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlayFromUri(@NonNull MediaSession2 session,
925d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull Uri uri,
926d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle extras) { }
927fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
928d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
929d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to prepare for playing a specific mediaId through
930d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#prepareFromMediaId(String, Bundle)}.
931d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
932d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * During the preparation, a session should not hold audio focus in order to allow other
933d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * sessions play seamlessly. The state of playback should be updated to
934d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
935d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
936d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * The playback of the prepared content should start in the later calls of
937d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaSession2#play()}.
938d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
939d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Override {@link #onPlayFromMediaId} to handle requests for starting
940d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * playback without preparation.
941d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
942d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
943d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
944d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param mediaId media id to prepare
945d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
946d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID
947d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
948d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPrepareFromMediaId(@NonNull MediaSession2 session,
949d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull String mediaId,
950d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle extras) { }
951fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
952d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
953d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to prepare playback from a search query through
954d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaController2#prepareFromSearch(String, Bundle)}.
955d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
956d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * An empty query indicates that the app may prepare any music. The implementation should
957d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * attempt to make a smart choice about what to play.
958d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
959d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * The state of playback should be updated to
960d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
961d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * The playback of the prepared content should start in the
962d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * later calls of {@link MediaSession2#play()}.
963d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
964d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Override {@link #onPlayFromSearch} to handle requests for starting playback without
965d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * preparation.
966d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
967d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
968d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
969d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param query query string. Can be empty to indicate any suggested media
970d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
971d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH
972d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
973d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPrepareFromSearch(@NonNull MediaSession2 session,
974d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull String query,
975d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable Bundle extras) { }
976fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
977d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
978d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller requested to prepare a specific media item represented by a URI
979d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * through {@link MediaController2#prepareFromUri(Uri, Bundle)}.
980d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
981d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * During the preparation, a session should not hold audio focus in order to allow
982d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * other sessions play seamlessly. The state of playback should be updated to
983d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaPlayerInterface#PLAYER_STATE_PAUSED} after the preparation is done.
984d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
985d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * The playback of the prepared content should start in the later calls of
986d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaSession2#play()}.
987d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
988d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Override {@link #onPlayFromUri} to handle requests for starting playback without
989d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * preparation.
990d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
991d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
992d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
993d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param uri uri
994d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param extras optional extra bundle
995d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_URI
996d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
997d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPrepareFromUri(@NonNull MediaSession2 session,
998d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull Uri uri, @Nullable Bundle extras) { }
999fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1000fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1001d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller called {@link MediaController2#fastForward()}
1002fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
1003d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1004d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
1005d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_FAST_FORWARD
1006fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1007d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onFastForward(@NonNull MediaSession2 session, ControllerInfo controller) { }
1008fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1009fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1010d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller called {@link MediaController2#rewind()}
1011fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
1012d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1013d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
1014d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_REWIND
1015fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1016d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onRewind(@NonNull MediaSession2 session, ControllerInfo controller) { }
1017fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1018fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1019d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller called {@link MediaController2#subscribeRoutesInfo()}
1020d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Session app should notify the routes information by calling
1021d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaSession2#notifyRoutesInfoChanged(ControllerInfo, List)}.
1022fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
1023d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1024d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
1025d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO
1026fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1027d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onSubscribeRoutesInfo(@NonNull MediaSession2 session,
1028d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller) { }
1029fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1030fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1031d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller called {@link MediaController2#unsubscribeRoutesInfo()}
1032fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
1033d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1034d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
1035d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO
1036fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1037d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onUnsubscribeRoutesInfo(@NonNull MediaSession2 session,
1038d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller) { }
1039fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1040fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1041d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a controller called {@link MediaController2#selectRoute(Bundle)}.
1042d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1043d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param controller controller information
1044d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param route The route bundle which may be from MediaRouteDescritor.asBundle().
1045d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see SessionCommand2#COMMAND_CODE_SESSION_SELECT_ROUTE
1046d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1047d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onSelectRoute(@NonNull MediaSession2 session,
1048d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull ControllerInfo controller, @NonNull Bundle route) { }
1049d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1050d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when the player's current playing item is changed
1051d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
1052d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * When it's called, you should invalidate previous playback information and wait for later
1053d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * callbacks.
1054fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         *
1055d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the controller for this event
1056d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player for this event
1057d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param item new item
1058fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1059d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onCurrentMediaItemChanged(@NonNull MediaSession2 session,
1060d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, @Nullable MediaItem2 item) { }
1061fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1062fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1063d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when the player is <i>prepared</i>, i.e. it is ready to play the content
1064d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * referenced by the given data source.
1065d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1066d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player for this event
1067d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param item the media item for which buffering is happening
1068fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1069d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onMediaPrepared(@NonNull MediaSession2 session,
1070d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, @NonNull MediaItem2 item) { }
1071fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1072fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1073d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called to indicate that the state of the player has changed.
1074d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * See {@link MediaPlayerInterface#getPlayerState()} for polling the player state.
1075d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1076d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player for this event
1077d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param state the new state of the player.
1078fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1079d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlayerStateChanged(@NonNull MediaSession2 session,
1080d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, @PlayerState int state) { }
1081fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1082fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /**
1083d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called to report buffering events for a data source.
1084d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1085d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1086d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player for this event
1087d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param item the media item for which buffering is happening.
1088d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param state the new buffering state.
1089fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
1090d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onBufferingStateChanged(@NonNull MediaSession2 session,
1091d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, @NonNull MediaItem2 item,
1092d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @BuffState int state) { }
1093fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1094d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1095d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called to indicate that the playback speed has changed.
1096d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1097d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player for this event
1098d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param speed the new playback speed.
1099d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1100d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlaybackSpeedChanged(@NonNull MediaSession2 session,
1101d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, float speed) { }
110203c696e779afb0f54668a8f76b0944ab3f1c9a29Hyundo Moon
1103d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1104d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called to indicate that {@link #seekTo(long)} is completed.
1105d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1106d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event.
1107d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player the player that has completed seeking.
1108d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param position the previous seeking request.
1109d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see #seekTo(long)
1110d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1111d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onSeekCompleted(@NonNull MediaSession2 session,
1112d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlayerInterface player, long position) { }
1113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1114d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1115d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a playlist is changed from the {@link MediaPlaylistAgent}.
1116d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
1117d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * This is called when the underlying agent has called
1118d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link PlaylistEventCallback#onPlaylistChanged(MediaPlaylistAgent,
1119d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * List, MediaMetadata2)}.
1120d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1121d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1122d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param playlistAgent playlist agent for this event
1123d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param list new playlist
1124d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param metadata new metadata
1125d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1126d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlaylistChanged(@NonNull MediaSession2 session,
1127d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlaylistAgent playlistAgent, @NonNull List<MediaItem2> list,
1128d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable MediaMetadata2 metadata) { }
1129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1130d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1131d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when a playlist metadata is changed.
1132d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1133d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1134d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param playlistAgent playlist agent for this event
1135d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param metadata new metadata
1136d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1137d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onPlaylistMetadataChanged(@NonNull MediaSession2 session,
1138d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlaylistAgent playlistAgent, @Nullable MediaMetadata2 metadata) { }
1139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1140d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1141d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when the shuffle mode is changed.
1142d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1143d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1144d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param playlistAgent playlist agent for this event
1145d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param shuffleMode repeat mode
1146d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
1147d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
1148d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
1149d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1150d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onShuffleModeChanged(@NonNull MediaSession2 session,
1151d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlaylistAgent playlistAgent,
1152d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @MediaPlaylistAgent.ShuffleMode int shuffleMode) { }
1153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1154d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1155d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Called when the repeat mode is changed.
1156d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1157d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param session the session for this event
1158d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param playlistAgent playlist agent for this event
1159d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param repeatMode repeat mode
1160d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#REPEAT_MODE_NONE
1161d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#REPEAT_MODE_ONE
1162d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#REPEAT_MODE_ALL
1163d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
1164d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1165d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public void onRepeatModeChanged(@NonNull MediaSession2 session,
1166d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull MediaPlaylistAgent playlistAgent,
1167d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @MediaPlaylistAgent.RepeatMode int repeatMode) { }
116803c696e779afb0f54668a8f76b0944ab3f1c9a29Hyundo Moon    }
116903c696e779afb0f54668a8f76b0944ab3f1c9a29Hyundo Moon
1170fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
1171d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Builder for {@link MediaSession2}.
1172fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
1173d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Any incoming event from the {@link MediaController2} will be handled on the thread
1174d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * that created session with the {@link Builder#build()}.
1175fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
1176d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public static final class Builder extends BuilderBase<MediaSession2, Builder, SessionCallback> {
1177d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private MediaSession2ImplBase.Builder mImpl;
1178fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1179d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public Builder(Context context) {
1180d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            super(context);
1181d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mImpl = new MediaSession2ImplBase.Builder(context);
1182d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            setImpl(mImpl);
1183fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1184fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1185d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1186d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setPlayer(@NonNull MediaPlayerInterface player) {
1187d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setPlayer(player);
1188d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1189fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1190d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1191d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) {
1192d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setPlaylistAgent(playlistAgent);
1193d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1194fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1195d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1196d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setVolumeProvider(@Nullable VolumeProviderCompat volumeProvider) {
1197d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setVolumeProvider(volumeProvider);
1198d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1199fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1200d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1201d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setSessionActivity(@Nullable PendingIntent pi) {
1202d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setSessionActivity(pi);
1203d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1204fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1205d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1206d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setId(@NonNull String id) {
1207d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setId(id);
1208d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1210d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1211d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Builder setSessionCallback(@NonNull Executor executor,
1212d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull SessionCallback callback) {
1213d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.setSessionCallback(executor, callback);
1214d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1215fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1216d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1217d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull MediaSession2 build() {
1218d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return super.build();
1219d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1221fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1222fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
1223d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Information of a controller.
1224fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
1225d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public static final class ControllerInfo {
1226d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private final int mUid;
1227d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private final String mPackageName;
1228d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private final boolean mIsTrusted;
1229d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private final ControllerCb mControllerCb;
1230fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1231d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1232d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @hide
1233d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1234d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @RestrictTo(LIBRARY_GROUP)
1235d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        ControllerInfo(@NonNull String packageName, int pid, int uid, @NonNull ControllerCb cb) {
1236d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mUid = uid;
1237d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mPackageName = packageName;
1238d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mIsTrusted = false;
1239d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mControllerCb = cb;
1240d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1241fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1242d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1243d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return package name of the controller
1244d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1245d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull String getPackageName() {
1246d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mPackageName;
1247d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1249d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1250d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return uid of the controller
1251d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1252d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public int getUid() {
1253d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mUid;
1254d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1256d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1257d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
1258d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * has a enabled notification listener so can be trusted to accept connection and incoming
1259d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * command request.
1260d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1261d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return {@code true} if the controller is trusted.
1262d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @hide
1263d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1264d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @RestrictTo(LIBRARY_GROUP)
1265d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public boolean isTrusted() {
1266d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mIsTrusted;
1267d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1268d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
1269d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1270d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public int hashCode() {
1271d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mControllerCb.hashCode();
1272d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1273fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1274d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1275d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public boolean equals(Object obj) {
1276d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (!(obj instanceof ControllerInfo)) {
1277d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return false;
1278d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1279d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            ControllerInfo other = (ControllerInfo) obj;
1280d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mControllerCb.equals(other.mControllerCb);
1281d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1282fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1283d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1284d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public String toString() {
1285d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return "ControllerInfo {pkg=" + mPackageName + ", uid=" + mUid + "})";
1286d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1288d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull IBinder getId() {
1289d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mControllerCb.getId();
1290d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1292d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull ControllerCb getControllerCb() {
1293d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mControllerCb;
1294d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
1298d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Button for a {@link SessionCommand2} that will be shown by the controller.
1299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
1300d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * It's up to the controller's decision to respect or ignore this customization request.
1301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
1302d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    public static final class CommandButton {
1303d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private static final String KEY_COMMAND =
1304d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                "android.media.media_session2.command_button.command";
1305d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private static final String KEY_ICON_RES_ID =
1306d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                "android.media.media_session2.command_button.icon_res_id";
1307d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private static final String KEY_DISPLAY_NAME =
1308d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                "android.media.media_session2.command_button.display_name";
1309d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private static final String KEY_EXTRAS =
1310d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                "android.media.media_session2.command_button.extras";
1311d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private static final String KEY_ENABLED =
1312d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                "android.media.media_session2.command_button.enabled";
1313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1314d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private SessionCommand2 mCommand;
1315d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private int mIconResId;
1316d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private String mDisplayName;
1317d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private Bundle mExtras;
1318d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private boolean mEnabled;
1319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1320d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        private CommandButton(@Nullable SessionCommand2 command, int iconResId,
1321d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable String displayName, Bundle extras, boolean enabled) {
1322d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mCommand = command;
1323d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mIconResId = iconResId;
1324d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mDisplayName = displayName;
1325d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mExtras = extras;
1326d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mEnabled = enabled;
1327d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1328fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1329d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1330d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Get command associated with this button. Can be {@code null} if the button isn't enabled
1331d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * and only providing placeholder.
1332d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1333d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return command or {@code null}
1334d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1335d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @Nullable SessionCommand2 getCommand() {
1336d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mCommand;
1337d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1338fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1339d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1340d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Resource id of the button in this package. Can be {@code 0} if the command is predefined
1341d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * and custom icon isn't needed.
1342d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1343d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return resource id of the icon. Can be {@code 0}.
1344d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1345d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public int getIconResId() {
1346d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mIconResId;
1347d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1348fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1349d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1350d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Display name of the button. Can be {@code null} or empty if the command is predefined
1351d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * and custom name isn't needed.
1352d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1353d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return custom display name. Can be {@code null} or empty.
1354d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1355d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @Nullable String getDisplayName() {
1356d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mDisplayName;
1357d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1358fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim
1359d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1360d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Extra information of the button. It's private information between session and controller.
1361d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1362d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return
1363d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1364d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @Nullable Bundle getExtras() {
1365d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mExtras;
1366d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1367fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1368d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1369d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Return whether it's enabled.
1370d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1371d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return {@code true} if enabled. {@code false} otherwise.
1372d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1373d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public boolean isEnabled() {
1374d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mEnabled;
1375d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1376fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1377d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1378d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @hide
1379d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return Bundle
1380d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1381d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @RestrictTo(LIBRARY_GROUP)
1382d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public @NonNull Bundle toBundle() {
1383d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            Bundle bundle = new Bundle();
1384d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            bundle.putBundle(KEY_COMMAND, mCommand.toBundle());
1385d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            bundle.putInt(KEY_ICON_RES_ID, mIconResId);
1386d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            bundle.putString(KEY_DISPLAY_NAME, mDisplayName);
1387d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            bundle.putBundle(KEY_EXTRAS, mExtras);
1388d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            bundle.putBoolean(KEY_ENABLED, mEnabled);
1389d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return bundle;
1390d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1391fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1392d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1393d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @hide
1394d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return CommandButton
1395d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1396d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @RestrictTo(LIBRARY_GROUP)
1397d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public static @Nullable CommandButton fromBundle(Bundle bundle) {
1398d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (bundle == null) {
1399d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return null;
1400d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1401d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            CommandButton.Builder builder = new CommandButton.Builder();
1402d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            builder.setCommand(SessionCommand2.fromBundle(bundle.getBundle(KEY_COMMAND)));
1403d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            builder.setIconResId(bundle.getInt(KEY_ICON_RES_ID, 0));
1404d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            builder.setDisplayName(bundle.getString(KEY_DISPLAY_NAME));
1405d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            builder.setExtras(bundle.getBundle(KEY_EXTRAS));
1406d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            builder.setEnabled(bundle.getBoolean(KEY_ENABLED));
1407d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            try {
1408d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return builder.build();
1409d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            } catch (IllegalStateException e) {
1410d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                // Malformed or version mismatch. Return null for now.
1411d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return null;
1412d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1413d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1414d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
1415d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1416d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Builder for {@link CommandButton}.
1417d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1418d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public static final class Builder {
1419d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            private SessionCommand2 mCommand;
1420d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            private int mIconResId;
1421d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            private String mDisplayName;
1422d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            private Bundle mExtras;
1423d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            private boolean mEnabled;
1424fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1425d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1426d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Sets the {@link SessionCommand2} that would be sent to the session when the button
1427d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * is clicked.
1428d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1429d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @param command session command
1430d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1431d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull Builder setCommand(@Nullable SessionCommand2 command) {
1432d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                mCommand = command;
1433d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return this;
1434d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1435fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1436d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1437d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Sets the bitmap-type (e.g. PNG) icon resource id of the button.
1438d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * <p>
1439d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * None bitmap type (e.g. VectorDrawabale) may cause unexpected behavior when it's sent
1440d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * to {@link MediaController2} app, so please avoid using it especially for the older
1441d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * platform (API < 21).
1442d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1443d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @param resId resource id of the button
1444d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1445d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull Builder setIconResId(int resId) {
1446d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                mIconResId = resId;
1447d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return this;
1448d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1449fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1450d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1451d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Sets the display name of the button.
1452d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1453d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @param displayName display name of the button
1454d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1455d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull Builder setDisplayName(@Nullable String displayName) {
1456d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                mDisplayName = displayName;
1457d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return this;
1458d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1460d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1461d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Sets whether the button is enabled. Can be {@code false} to indicate that the button
1462d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * should be shown but isn't clickable.
1463d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1464d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @param enabled {@code true} if the button is enabled and ready.
1465d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *          {@code false} otherwise.
1466d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1467d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull Builder setEnabled(boolean enabled) {
1468d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                mEnabled = enabled;
1469d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return this;
1470d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1471fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1472d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1473d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Sets the extras of the button.
1474d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1475d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @param extras extras information of the button
1476d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1477d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull Builder setExtras(@Nullable Bundle extras) {
1478d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                mExtras = extras;
1479d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return this;
1480d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1482d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            /**
1483d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * Builds the {@link CommandButton}.
1484d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             *
1485d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             * @return a new {@link CommandButton}
1486d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim             */
1487d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            public @NonNull CommandButton build() {
1488d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return new CommandButton(mCommand, mIconResId, mDisplayName, mExtras, mEnabled);
1489d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1490d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1491fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1492fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1493d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    abstract static class ControllerCb {
1494d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1495d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public int hashCode() {
1496d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return getId().hashCode();
1497d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1498fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1499d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @Override
1500d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        public boolean equals(Object obj) {
1501d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (!(obj instanceof ControllerCb)) {
1502d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                return false;
1503d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1504d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            ControllerCb other = (ControllerCb) obj;
1505d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return getId().equals(other.getId());
1506d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1507fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1508d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @NonNull IBinder getId();
15092b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim
15102b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        // Mostly matched with the methods in MediaController2.ControllerCallback
15112b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onCustomLayoutChanged(@NonNull List<CommandButton> layout)
15122b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15132b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onPlaybackInfoChanged(@NonNull PlaybackInfo info) throws RemoteException;
15142b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onAllowedCommandsChanged(@NonNull SessionCommandGroup2 commands)
15152b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15162b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
15172b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                @Nullable ResultReceiver receiver) throws RemoteException;
15182b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onPlayerStateChanged(int playerState) throws RemoteException;
15192b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onPlaybackSpeedChanged(float speed) throws RemoteException;
15202b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onBufferingStateChanged(@NonNull MediaItem2 item,
15212b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                @MediaPlayerInterface.BuffState int state) throws RemoteException;
15222b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onSeekCompleted(long position) throws RemoteException;
15232b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onError(@ErrorCode int errorCode, @Nullable Bundle extras)
15242b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15252b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onCurrentMediaItemChanged(@Nullable MediaItem2 item) throws RemoteException;
15262b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onPlaylistChanged(@NonNull List<MediaItem2> playlist,
15272b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                @Nullable MediaMetadata2 metadata) throws RemoteException;
15282b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onPlaylistMetadataChanged(@Nullable MediaMetadata2 metadata)
15292b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15302b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onShuffleModeChanged(@MediaPlaylistAgent.ShuffleMode int shuffleMode)
15312b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15322b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onRepeatModeChanged(@MediaPlaylistAgent.RepeatMode int repeatMode)
15332b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                throws RemoteException;
15342b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onRoutesInfoChanged(@Nullable List<Bundle> routes) throws RemoteException;
15352b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onChildrenChanged(@NonNull  String parentId, int itemCount,
15362b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                @Nullable Bundle extras) throws RemoteException;
15372b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim        abstract void onSearchResultChanged(@NonNull String query, int itemCount,
15382b3e8e641d6ea839eb6e8b458f3c3a1015f91665Sungsoo Lim                @Nullable Bundle extras) throws RemoteException;
1539fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1540fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1541d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    abstract static class SupportLibraryImpl extends MediaInterface2.SessionPlayer
1542d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            implements AutoCloseable {
1543d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void updatePlayer(@NonNull MediaPlayerInterface player,
1544d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable MediaPlaylistAgent playlistAgent,
1545d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable VolumeProviderCompat volumeProvider);
1546d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @NonNull MediaPlayerInterface getPlayer();
1547d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @NonNull MediaPlaylistAgent getPlaylistAgent();
1548d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @Nullable VolumeProviderCompat getVolumeProvider();
1549d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @NonNull SessionToken2 getToken();
1550d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract @NonNull List<ControllerInfo> getConnectedControllers();
1551fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1552d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void setAudioFocusRequest(@Nullable AudioFocusRequest afr);
1553d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void setCustomLayout(@NonNull ControllerInfo controller,
1554d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull List<CommandButton> layout);
1555d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void setAllowedCommands(@NonNull ControllerInfo controller,
1556d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull SessionCommandGroup2 commands);
1557d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args);
1558d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void sendCustomCommand(@NonNull ControllerInfo controller,
1559d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull SessionCommand2 command, @Nullable Bundle args,
1560d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable ResultReceiver receiver);
1561d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void notifyRoutesInfoChanged(@NonNull ControllerInfo controller,
1562d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @Nullable List<Bundle> routes);
1563fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1564d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        // LibrarySession methods
1565e643575a509d0062168f789de14d10ef84280c1dHyundo Moon        abstract void notifyChildrenChanged(@NonNull ControllerInfo controller,
1566e643575a509d0062168f789de14d10ef84280c1dHyundo Moon                @NonNull String parentId, int itemCount, @Nullable Bundle extras,
1567e643575a509d0062168f789de14d10ef84280c1dHyundo Moon                @NonNull List<MediaSessionManager.RemoteUserInfo> subscribingBrowsers);
1568d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract void notifySearchResultChanged(@NonNull ControllerInfo controller,
1569d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                @NonNull String query, int itemCount, @Nullable Bundle extras);
1570d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
1571d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        // Internally used methods
1572a6d5aa35ee1462189da3add16b7b874de2ecb60fJaewan Kim        abstract MediaSession2 createInstance();
1573d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract MediaSession2 getInstance();
1574d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract MediaSessionCompat getSessionCompat();
1575d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract Context getContext();
1576d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract Executor getCallbackExecutor();
1577d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract SessionCallback getCallback();
1578d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract boolean isClosed();
1579d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract PlaybackStateCompat getPlaybackStateCompat();
1580d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        abstract PlaybackInfo getPlaybackInfo();
1581fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1582fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1583fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
1584d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Base builder class for MediaSession2 and its subclass. Any change in this class should be
1585d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * also applied to the subclasses {@link MediaSession2.Builder} and
1586d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * {@link MediaLibraryService2.MediaLibrarySession.Builder}.
1587fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * <p>
1588d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * APIs here should be package private, but should have documentations for developers.
1589d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * Otherwise, javadoc will generate documentation with the generic types such as follows.
1590d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <pre>U extends BuilderBase<T, U, C> setSessionCallback(Executor executor, C callback)</pre>
1591d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <p>
1592d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * This class is hidden to prevent from generating test stub, which fails with
1593d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * 'unexpected bound' because it tries to auto generate stub class as follows.
1594d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * <pre>abstract static class BuilderBase<
1595d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      T extends android.media.MediaSession2,
1596d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *      U extends android.media.MediaSession2.BuilderBase<
1597d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     *              T, U, C extends android.media.MediaSession2.SessionCallback>, C></pre>
1598d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim     * @hide
1599fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
1600d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    @RestrictTo(LIBRARY_GROUP)
1601d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim    abstract static class BuilderBase
1602d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            <T extends MediaSession2, U extends BuilderBase<T, U, C>, C extends SessionCallback> {
1603d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        final Context mContext;
1604d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        MediaSession2ImplBase.BuilderBase<T, C> mBaseImpl;
1605d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        MediaPlayerInterface mPlayer;
1606d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        String mId;
1607d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        Executor mCallbackExecutor;
1608d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        C mCallback;
1609d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        MediaPlaylistAgent mPlaylistAgent;
1610d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        VolumeProviderCompat mVolumeProvider;
1611d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        PendingIntent mSessionActivity;
1612fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1613d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        BuilderBase(Context context) {
1614d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (context == null) {
1615d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("context shouldn't be null");
1616d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1617d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mContext = context;
1618d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            // Ensure non-null
1619d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mId = "";
1620d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1621fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1622d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1623d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Sets the underlying {@link MediaPlayerInterface} for this session to dispatch incoming
1624d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * event to.
1625d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1626d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param player a {@link MediaPlayerInterface} that handles actual media playback in your
1627d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *               app.
1628d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1629d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull U setPlayer(@NonNull MediaPlayerInterface player) {
1630d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (player == null) {
1631d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("player shouldn't be null");
1632d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1633d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setPlayer(player);
1634d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1635d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1636fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1637d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1638d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Sets the {@link MediaPlaylistAgent} for this session to manages playlist of the
1639d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * underlying {@link MediaPlayerInterface}. The playlist agent should manage
1640d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaPlayerInterface} for calling
1641d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * {@link MediaPlayerInterface#setNextDataSources(List)}.
1642d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
1643d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * If the {@link MediaPlaylistAgent} isn't set, session will create the default playlist
1644d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * agent.
1645d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1646d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the
1647d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *                      {@code player}
1648d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1649d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        U setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) {
1650d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (playlistAgent == null) {
1651d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("playlistAgent shouldn't be null");
1652d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1653d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setPlaylistAgent(playlistAgent);
1654d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1655d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1656fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1657d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1658d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Sets the {@link VolumeProviderCompat} for this session to handle volume events. If not
1659d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * set, system will adjust the appropriate stream volume for this session's player.
1660d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1661d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param volumeProvider The provider that will receive volume button events.
1662d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1663d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull U setVolumeProvider(@Nullable VolumeProviderCompat volumeProvider) {
1664d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setVolumeProvider(volumeProvider);
1665d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1666d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1667fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1668d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1669d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Set an intent for launching UI for this Session. This can be used as a
1670d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * quick link to an ongoing media screen. The intent should be for an
1671d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * activity that may be started using {@link Context#startActivity(Intent)}.
1672d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1673d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param pi The intent to launch to show UI for this session.
1674d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1675d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull U setSessionActivity(@Nullable PendingIntent pi) {
1676d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setSessionActivity(pi);
1677d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1678d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1679fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1680d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1681d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Set ID of the session. If it's not set, an empty string with used to create a session.
1682d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * <p>
1683d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Use this if and only if your app supports multiple playback at the same time and also
1684d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * wants to provide external apps to have finer controls of them.
1685d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1686d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param id id of the session. Must be unique per package.
1687d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @throws IllegalArgumentException if id is {@code null}
1688d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return
1689d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1690d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull U setId(@NonNull String id) {
1691d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (id == null) {
1692d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("id shouldn't be null");
1693d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1694d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setId(id);
1695d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1696d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1697fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1698d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1699d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Set callback for the session.
1700d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1701d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param executor callback executor
1702d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @param callback session callback.
1703d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return
1704d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1705d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull U setSessionCallback(@NonNull Executor executor, @NonNull C callback) {
1706d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (executor == null) {
1707d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("executor shouldn't be null");
1708d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1709d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            if (callback == null) {
1710d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim                throw new IllegalArgumentException("callback shouldn't be null");
1711d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            }
1712d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl.setSessionCallback(executor, callback);
1713d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return (U) this;
1714d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1715d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
1716d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        /**
1717d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * Build {@link MediaSession2}.
1718d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *
1719d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @return a new session
1720d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         * @throws IllegalStateException if the session with the same id is already exists for the
1721d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         *      package.
1722d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim         */
1723d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        @NonNull T build() {
1724d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            return mBaseImpl.build();
1725d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1726d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim
1727d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        void setImpl(MediaSession2ImplBase.BuilderBase<T, C> impl) {
1728d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim            mBaseImpl = impl;
1729d4b75f948cae91cd86c701011af67a6125f9322eSungsoo Lim        }
1730fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1731fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang}
1732