MediaSession2Test.java revision fbbf807584a0fbe7a01a0aa9920330cad45689aa
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 android.media.AudioAttributes.CONTENT_TYPE_MUSIC;
20fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
21fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertEquals;
22fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertFalse;
23fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNotEquals;
24fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNotNull;
25fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNull;
26fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertSame;
27fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertTrue;
28fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.fail;
29fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
30fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.Context;
31fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.AudioManager;
32fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Build;
33fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Bundle;
34fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Process;
35fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.ResultReceiver;
36fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.SdkSuppress;
37fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.SmallTest;
38fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.runner.AndroidJUnit4;
39fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
40fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.NonNull;
41fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaController2.ControllerCallback;
42fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaController2.PlaybackInfo;
43fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.CommandButton;
44fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.ControllerInfo;
45fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.SessionCallback;
46fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
47fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport junit.framework.Assert;
48fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
49fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.After;
50fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Before;
51fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Ignore;
52fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Test;
53fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.runner.RunWith;
54fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
55fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.ArrayList;
56fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.List;
57fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.Set;
58fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.CountDownLatch;
59fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.TimeUnit;
60fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
61fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang/**
62fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Tests {@link MediaSession2}.
63fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang */
64fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
65fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@RunWith(AndroidJUnit4.class)
66fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@SmallTest
67fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangpublic class MediaSession2Test extends MediaSession2TestBase {
68fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final String TAG = "MediaSession2Test";
69fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
70fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MediaSession2 mSession;
71fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MockPlayer mPlayer;
72fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MockPlaylistAgent mMockAgent;
73fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
74fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Before
75fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
76fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void setUp() throws Exception {
77fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.setUp();
78fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer = new MockPlayer(0);
79fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent = new MockPlaylistAgent();
80fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
81fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession = new MediaSession2.Builder(mContext)
82fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
83fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
84fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
85fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
86fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public SessionCommandGroup2 onConnect(MediaSession2 session,
87fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            ControllerInfo controller) {
88fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        if (Process.myUid() == controller.getUid()) {
89fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            return super.onConnect(session, controller);
90fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
91fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        return null;
92fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
93fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build();
94fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
95fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
96fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @After
97fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
98fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void cleanUp() throws Exception {
99fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.cleanUp();
100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.close();
101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBuilder() {
105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaSession2.Builder builder = new MediaSession2.Builder(mContext);
107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            builder.setPlayer(null);
109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            fail("null player shouldn't be allowed");
110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } catch (IllegalArgumentException e) {
111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // expected. pass-through
112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            builder.setId(null);
115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            fail("null id shouldn't be allowed");
116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } catch (IllegalArgumentException e) {
117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // expected. pass-through
118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayerStateChange() throws Exception {
123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int targetState = MediaPlayerBase.PLAYER_STATE_PLAYING;
125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext)
131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setPlayer(mPlayer)
132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, new SessionCallback() {
133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            @Override
134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            public void onPlayerStateChanged(MediaSession2 session,
135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                    MediaPlayerBase player, int state) {
136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                assertEquals(targetState, state);
137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                latchForSessionCallback.countDown();
138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }).build();
140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForControllerCallback = new CountDownLatch(1);
144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller =
145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                createController(mSession.getToken(), true, new ControllerCallback() {
146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onPlayerStateChanged(MediaController2 controllerOut, int state) {
148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(targetState, state);
149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForControllerCallback.countDown();
150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
151fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                });
152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_PLAYING);
154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
156fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(targetState, controller.getPlayerState());
157fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testCurrentDataSourceChanged() throws Exception {
161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
164fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
165fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
166fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
167fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
168fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
169fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
170fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
171fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testCurrentDataSourceChanged")
172fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
173fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
174fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onCurrentMediaItemChanged(MediaSession2 session,
175fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            MediaPlayerBase player, MediaItem2 itemOut) {
176fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertSame(currentItem, itemOut);
177fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
178fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
179fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
180fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
181fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyCurrentDataSourceChanged(currentItem.getDataSourceDesc());
182fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
183fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO(jaewan): Test that controllers are also notified. (b/74505936)
184fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
185fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
186fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
187fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
188fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testMediaPrepared() throws Exception {
189fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
190fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
191fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
192fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
193fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
194fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
195fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
196fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
197fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
198fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
199fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
200fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testMediaPrepared")
201fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
202fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
203fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onMediaPrepared(MediaSession2 session, MediaPlayerBase player,
204fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            MediaItem2 itemOut) {
205fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertSame(currentItem, itemOut);
206fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
207fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
208fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
210fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyMediaPrepared(currentItem.getDataSourceDesc());
211fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
212fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO(jaewan): Test that controllers are also notified. (b/74505936)
213fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
214fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
215fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
216fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
217fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBufferingStateChanged() throws Exception {
218fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
219fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
221fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
222fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
223fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
224fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int buffState = MediaPlayerBase.BUFFERING_STATE_BUFFERING_COMPLETE;
225fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
226fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
227fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
228fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
229fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
230fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testBufferingStateChanged")
231fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
232fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
233fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onBufferingStateChanged(MediaSession2 session,
234fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            MediaPlayerBase player, MediaItem2 itemOut, int stateOut) {
235fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertSame(currentItem, itemOut);
236fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(buffState, stateOut);
237fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
239fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
240fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
241fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyBufferingStateChanged(currentItem.getDataSourceDesc(), buffState);
242fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
243fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO(jaewan): Test that controllers are also notified. (b/74505936)
244fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
245fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
247fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testUpdatePlayer() throws Exception {
249fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
250fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int targetState = MediaPlayerBase.PLAYER_STATE_PLAYING;
251fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
252fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
253fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
254fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
256fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
257fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, new SessionCallback() {
258fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            @Override
259fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            public void onPlayerStateChanged(MediaSession2 session,
260fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                    MediaPlayerBase player, int state) {
261fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                assertEquals(targetState, state);
262fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                latch.countDown();
263fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
264fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }).build();
265fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
266fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
267fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
268fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MockPlayer player = new MockPlayer(0);
269fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
270fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test if setPlayer doesn't crash with various situations.
271fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(mPlayer, null, null);
272fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(mPlayer, mSession.getPlayer());
273fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlaylistAgent agent = mSession.getPlaylistAgent();
274fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(agent);
275fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
276fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
277fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(player, mSession.getPlayer());
278fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(mSession.getPlaylistAgent());
279fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotEquals(agent, mSession.getPlaylistAgent());
280fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
281fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        player.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_PLAYING);
282fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
283fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
284fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
285fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Ignore
286fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetPlayer_playbackInfo() throws Exception {
288fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MockPlayer player = new MockPlayer(0);
290fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setContentType(CONTENT_TYPE_MUSIC)
292fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build();
293fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        player.setAudioAttributes(attrs);
294fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int maxVolume = 100;
296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int currentVolume = 23;
297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
298fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        VolumeProviderCompat volumeProvider =
299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                new VolumeProviderCompat(volumeControlType, maxVolume, currentVolume) {
300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                };
301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
302fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
303fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
304fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
305fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onPlaybackInfoChanged(MediaController2 controller, PlaybackInfo info) {
306fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Assert.assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
307fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(attrs, info.getAudioAttributes());
308fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(volumeControlType, info.getPlaybackType());
309fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(maxVolume, info.getMaxVolume());
310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(currentVolume, info.getCurrentVolume());
311fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
312fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
314fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
315fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
316fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
317fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
318fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        PlaybackInfo info = controller.getPlaybackInfo();
319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(info);
320fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(PlaybackInfo.PLAYBACK_TYPE_LOCAL, info.getPlaybackType());
321fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(attrs, info.getAudioAttributes());
322fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
323fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int localVolumeControlType = manager.isVolumeFixed()
324fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ? VolumeProviderCompat.VOLUME_CONTROL_FIXED
325fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                : VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
326fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(localVolumeControlType, info.getControlType());
327fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), info.getMaxVolume());
328fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(manager.getStreamVolume(AudioManager.STREAM_MUSIC), info.getCurrentVolume());
329fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
330fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, volumeProvider);
331fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
332fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
333fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        info = controller.getPlaybackInfo();
334fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(info);
335fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
336fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(attrs, info.getAudioAttributes());
337fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(volumeControlType, info.getControlType());
338fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(maxVolume, info.getMaxVolume());
339fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(currentVolume, info.getCurrentVolume());
340fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
341fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
342fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
343fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlay() throws Exception {
344fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
345fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.play();
346fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPlayCalled);
347fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
348fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
349fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
350fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPause() throws Exception {
351fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
352fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.pause();
353fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPauseCalled);
354fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
355fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
356fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
357fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testReset() throws Exception {
358fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
359fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.reset();
360fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mResetCalled);
361fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
362fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
363fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
364fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPrepare() throws Exception {
365fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
366fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.prepare();
367fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPrepareCalled);
368fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
369fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
370fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
371fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSeekTo() throws Exception {
372fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
373fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long pos = 1004L;
374fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.seekTo(pos);
375fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mSeekToCalled);
376fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(pos, mPlayer.mSeekPosition);
377fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
378fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
379fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
380fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToPreviousItem() {
381fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
382fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToPreviousItem();
383fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToPreviousItemCalled);
384fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
385fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
386fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
387fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToNextItem() throws Exception {
388fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
389fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToNextItem();
390fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToNextItemCalled);
391fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
392fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
393fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
394fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToPlaylistItem() throws Exception {
395fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
396fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
397fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToPlaylistItem(testMediaItem);
398fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToPlaylistItemCalled);
399fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
400fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
401fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
402fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
403fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlayerState() {
404fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
405fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int state = MediaPlayerBase.PLAYER_STATE_PLAYING;
406fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mLastPlayerState = state;
407fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(state, mSession.getPlayerState());
408fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
409fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
410fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
411fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPosition() {
412fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
413fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long position = 150000;
414fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mCurrentPosition = position;
415fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(position, mSession.getCurrentPosition());
416fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
417fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
418fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
419fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetBufferedPosition() {
420fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
421fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long bufferedPosition = 900000;
422fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mBufferedPosition = bufferedPosition;
423fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(bufferedPosition, mSession.getBufferedPosition());
424fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
425fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
426fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
427fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetPlaylist() {
428fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
429fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
430fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setPlaylist(list, null);
431fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetPlaylistCalled);
432fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(list, mMockAgent.mPlaylist);
433fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNull(mMockAgent.mMetadata);
434fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
435fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
436fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
437fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlaylist() {
438fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
439fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
440fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.mPlaylist = list;
441fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(list, mSession.getPlaylist());
442fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
443fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
444fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
445fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testUpdatePlaylistMetadata() {
446fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
447fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaMetadata2 testMetadata = TestUtils.createMetadata();
448fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlaylistMetadata(testMetadata);
449fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mUpdatePlaylistMetadataCalled);
450fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMetadata, mMockAgent.mMetadata);
451fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
452fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
453fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
454fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlaylistMetadata() {
455fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
456fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaMetadata2 testMetadata = TestUtils.createMetadata();
457fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.mMetadata = testMetadata;
458fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testMetadata, mSession.getPlaylistMetadata());
459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
460fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
461fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
462fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSessionCallback_onPlaylistChanged() throws InterruptedException {
463fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
464fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
465fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
466fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
467fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
468fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
469fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
470fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onPlaylistChanged(MediaSession2 session, MediaPlaylistAgent playlistAgent,
471fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    List<MediaItem2> playlist, MediaMetadata2 metadata) {
472fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
473fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(list, playlist);
474fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNull(metadata);
475fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
476fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
477fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
478fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
479fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
480fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testSessionCallback")
482fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
483fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
484fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyPlaylistChanged();
485fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
486fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
487fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
488fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
489fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
490fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testAddPlaylistItem() {
491fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
492fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testIndex = 12;
493fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
494fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.addPlaylistItem(testIndex, testMediaItem);
495fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mAddPlaylistItemCalled);
496fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testIndex, mMockAgent.mIndex);
497fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
498fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
499fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
500fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
501fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRemovePlaylistItem() {
502fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
503fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
504fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.removePlaylistItem(testMediaItem);
505fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mRemovePlaylistItemCalled);
506fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
507fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
508fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
509fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
510fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testReplacePlaylistItem() throws InterruptedException {
511fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
512fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testIndex = 12;
513fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
514fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.replacePlaylistItem(testIndex, testMediaItem);
515fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mReplacePlaylistItemCalled);
516fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testIndex, mMockAgent.mIndex);
517fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
518fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
519fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
520fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
521fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * This also tests {@link SessionCallback#onShuffleModeChanged}
522fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
523fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
524fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetShuffleMode() throws InterruptedException {
525fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
526fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
527fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setShuffleMode(testShuffleMode);
528fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
529fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
530fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
531fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
532fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onShuffleModeChanged(MediaSession2 session,
533fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    MediaPlaylistAgent playlistAgent, int shuffleMode) {
534fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
535fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testShuffleMode, shuffleMode);
536fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
537fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
538fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
539fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
540fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
541fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
542fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testGetShuffleMode")
543fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
544fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
545fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyShuffleModeChanged();
546fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
547fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
548fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
549fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
550fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
551fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetShuffleMode() {
552fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
553fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
554fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setShuffleMode(testShuffleMode);
555fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetShuffleModeCalled);
556fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testShuffleMode, mMockAgent.mShuffleMode);
557fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
558fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
559fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
560fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * This also tests {@link SessionCallback#onShuffleModeChanged}
561fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
562fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
563fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetRepeatMode() throws InterruptedException {
564fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
565fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
566fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setRepeatMode(testRepeatMode);
567fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
568fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
569fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
570fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
571fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onRepeatModeChanged(MediaSession2 session, MediaPlaylistAgent playlistAgent,
572fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    int repeatMode) {
573fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
574fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testRepeatMode, repeatMode);
575fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
576fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
577fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
578fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
579fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
580fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
581fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testGetRepeatMode")
582fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
583fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
584fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyRepeatModeChanged();
585fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
586fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
587fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
588fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
589fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
590fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetRepeatMode() {
591fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
592fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
593fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setRepeatMode(testRepeatMode);
594fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetRepeatModeCalled);
595fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testRepeatMode, mMockAgent.mRepeatMode);
596fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
597fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
598fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // TODO(jaewan): Revisit
599fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Ignore
600fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
601fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBadPlayer() throws InterruptedException {
602fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
603fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Add equivalent tests again
604fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(4); // expected call + 1
605fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final BadPlayer player = new BadPlayer(0);
606fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
607fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
608fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(mPlayer, null, null);
609fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        player.notifyPlaybackState(MediaPlayerBase.PLAYER_STATE_PAUSED);
610fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
611fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
612fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
613fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // This bad player will keep push events to the listener that is previously
614fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // registered by session.setPlayer().
615fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static class BadPlayer extends MockPlayer {
616fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        BadPlayer(int count) {
617fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            super(count);
618fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
619fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
620fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
621fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public void unregisterPlayerEventCallback(
622fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                @NonNull MediaPlayerBase.PlayerEventCallback listener) {
623fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // No-op.
624fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
625fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
626fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
627fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
628fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnCommandCallback() throws InterruptedException {
629fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
630fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MockOnCommandCallback callback = new MockOnCommandCallback();
631fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
632fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
633fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
634fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
635fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mPlayer = new MockPlayer(1);
636fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
637fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, callback).build();
638fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
639fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
640fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaController2 controller = createController(mSession.getToken());
641fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        controller.pause();
642fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
643fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mPauseCalled);
644fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(1, callback.commands.size());
645fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE,
646fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                (long) callback.commands.get(0).getCommandCode());
647fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
648fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        controller.play();
649fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
650fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPlayCalled);
651fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mPauseCalled);
652fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(2, callback.commands.size());
653fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY,
654fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                (long) callback.commands.get(1).getCommandCode());
655fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
656fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
657fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
658fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnConnectCallback() throws InterruptedException {
659fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
660fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MockOnConnectCallback sessionCallback = new MockOnConnectCallback();
661fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
662fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
663fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
664fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
665fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
666fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, sessionCallback).build();
667fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
668fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
669fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaController2 controller = createController(mSession.getToken(), false, null);
670fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controller);
671fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        waitForConnect(controller, false);
672fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        waitForDisconnect(controller, true);
673fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
674fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
675fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
676fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnDisconnectCallback() throws InterruptedException {
677fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
678fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
679fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
680fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
681fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testOnDisconnectCallback")
682fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
683fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
684fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onDisconnected(MediaSession2 session,
685fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            ControllerInfo controller) {
686fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(Process.myUid(), controller.getUid());
687fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latch.countDown();
688fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
689fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
690fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaController2 controller = createController(session.getToken());
691fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            controller.close();
692fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
693fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
694fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
695fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
696fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
697fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetCustomLayout() throws InterruptedException {
698fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
699fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<CommandButton> buttons = new ArrayList<>();
700fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        buttons.add(new CommandButton.Builder()
701fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY))
702fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDisplayName("button").build());
703fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
704fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
705fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
706fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public SessionCommandGroup2 onConnect(MediaSession2 session,
707fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    ControllerInfo controller) {
708fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (mContext.getPackageName().equals(controller.getPackageName())) {
709fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mSession.setCustomLayout(controller, buttons);
710fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
711fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return super.onConnect(session, controller);
712fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
713fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
714fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
715fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
716fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
717fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testSetCustomLayout")
718fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
719fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
720fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (mSession != null) {
721fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
722fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = session;
723fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
724fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final ControllerCallback callback = new ControllerCallback() {
725fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                @Override
726fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                public void onCustomLayoutChanged(MediaController2 controller2,
727fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        List<CommandButton> layout) {
728fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    assertEquals(layout.size(), buttons.size());
729fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    for (int i = 0; i < layout.size(); i++) {
730fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(layout.get(i).getCommand(), buttons.get(i).getCommand());
731fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(layout.get(i).getDisplayName(),
732fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                buttons.get(i).getDisplayName());
733fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
734fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    latch.countDown();
735fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
736fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            };
737fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final MediaController2 controller =
738fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    createController(session.getToken(), true, callback);
739fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
740fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
741fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
742fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
743fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
744fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetAllowedCommands() throws InterruptedException {
745fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
746fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCommandGroup2 commands = new SessionCommandGroup2();
747fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY));
748fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE));
749fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_RESET));
750fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
751fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
752fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
753fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
754fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onAllowedCommandsChanged(MediaController2 controller,
755fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    SessionCommandGroup2 commandsOut) {
756fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNotNull(commandsOut);
757fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Set<SessionCommand2> expected = commands.getCommands();
758fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Set<SessionCommand2> actual = commandsOut.getCommands();
759fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
760fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNotNull(actual);
761fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(expected.size(), actual.size());
762fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                for (SessionCommand2 command : expected) {
763fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    assertTrue(actual.contains(command));
764fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
765fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
766fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
767fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
768fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
769fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
770fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ControllerInfo controllerInfo = getTestControllerInfo();
771fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllerInfo);
772fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
773fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setAllowedCommands(controllerInfo, commands);
774fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
775fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
776fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
777fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
778fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSendCustomCommand() throws InterruptedException {
779fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
780fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCommand2 testCommand = new SessionCommand2(
781fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
782fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Bundle testArgs = new Bundle();
783fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testArgs.putString("args", "testSendCustomAction");
784fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
785fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(2);
786fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
787fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
788fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCustomCommand(MediaController2 controller, SessionCommand2 command,
789fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    Bundle args, ResultReceiver receiver) {
790fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testCommand, command);
791fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(TestUtils.equals(testArgs, args));
792fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNull(receiver);
793fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
794fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
795fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
796fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller =
797fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                createController(mSession.getToken(), true, callback);
798fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test with multiple controllers
799fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.sendCustomCommand(testCommand, testArgs);
800fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
801fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ControllerInfo controllerInfo = getTestControllerInfo();
802fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllerInfo);
803fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test receivers as well.
804fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.sendCustomCommand(controllerInfo, testCommand, testArgs, null);
805fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
806fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
807fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
808fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
809fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testNotifyError() throws InterruptedException {
810fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
811fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int errorCode = MediaSession2.ERROR_CODE_NOT_AVAILABLE_IN_REGION;
812fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Bundle extras = new Bundle();
813fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        extras.putString("args", "testNotifyError");
814fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
815fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
816fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
817fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
818fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onError(MediaController2 controller, int errorCodeOut, Bundle extrasOut) {
819fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(errorCode, errorCodeOut);
820fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(TestUtils.equals(extras, extrasOut));
821fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
822fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
823fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
824fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
825fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test with multiple controllers
826fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.notifyError(errorCode, extras);
827fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
828fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
829fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
830fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private ControllerInfo getTestControllerInfo() {
831fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        List<ControllerInfo> controllers = mSession.getConnectedControllers();
832fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllers);
833fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < controllers.size(); i++) {
834fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (Process.myUid() == controllers.get(i).getUid()) {
835fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return controllers.get(i);
836fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
837fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
838fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        fail("Failed to get test controller info");
839fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return null;
840fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
841fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
842fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public class MockOnConnectCallback extends SessionCallback {
843fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
844fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public SessionCommandGroup2 onConnect(MediaSession2 session,
845fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ControllerInfo controllerInfo) {
846fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (Process.myUid() != controllerInfo.getUid()) {
847fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return null;
848fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
849fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
850fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(Process.myUid(), controllerInfo.getUid());
851fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(controllerInfo.isTrusted());
852fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Reject all
853fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return null;
854fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
855fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
856fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
857fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public class MockOnCommandCallback extends SessionCallback {
858fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public final ArrayList<SessionCommand2> commands = new ArrayList<>();
859fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
860fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
861fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public boolean onCommandRequest(MediaSession2 session, ControllerInfo controllerInfo,
862fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                SessionCommand2 command) {
863fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
864fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(Process.myUid(), controllerInfo.getUid());
865fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(controllerInfo.isTrusted());
866fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            commands.add(command);
867fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (command.getCommandCode() == SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE) {
868fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return false;
869fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
870fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return true;
871fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
872fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
873fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
874fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static void assertMediaItemListEquals(List<MediaItem2> a, List<MediaItem2> b) {
875fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (a == null || b == null) {
876fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(a, b);
877fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
878fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(a.size(), b.size());
879fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
880fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < a.size(); i++) {
881fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaItem2 aItem = a.get(i);
882fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaItem2 bItem = b.get(i);
883fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
884fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (aItem == null || bItem == null) {
885fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(aItem, bItem);
886fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                continue;
887fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
888fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
889fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(aItem.getMediaId(), bItem.getMediaId());
890fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(aItem.getFlags(), bItem.getFlags());
891fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            TestUtils.equals(aItem.getMetadata().toBundle(), bItem.getMetadata().toBundle());
892fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
893fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Note: Here it does not check whether DataSourceDesc are equal,
894fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // since there DataSourceDec is not comparable.
895fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
896fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
897fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang}
898