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
21f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moonimport static androidx.media.VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
22f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moonimport static androidx.media.VolumeProviderCompat.VOLUME_CONTROL_FIXED;
23f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon
24fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertEquals;
25fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertFalse;
26fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNotEquals;
27fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNotNull;
28fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNull;
29fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertSame;
30fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertTrue;
31fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.fail;
32fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
33fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.Context;
34fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.AudioManager;
35fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Build;
36fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Bundle;
37fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Process;
38fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.ResultReceiver;
39fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.SdkSuppress;
40fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.SmallTest;
41fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.runner.AndroidJUnit4;
42fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
43fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.annotation.NonNull;
44fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Limimport androidx.annotation.Nullable;
45fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaController2.ControllerCallback;
46fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaController2.PlaybackInfo;
47fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.CommandButton;
48fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.ControllerInfo;
49fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.MediaSession2.SessionCallback;
50fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
51fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport junit.framework.Assert;
52fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
53fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.After;
54fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Before;
55fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Ignore;
56fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Test;
57fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.runner.RunWith;
58fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
59fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.ArrayList;
60fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.List;
61fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.Set;
62fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.CountDownLatch;
63fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.TimeUnit;
64fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
65fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang/**
66fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang * Tests {@link MediaSession2}.
67fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang */
680607eb1068e49e97490c8923b68b883f45dba399Hyundo Moon@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
69fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@RunWith(AndroidJUnit4.class)
70fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@SmallTest
71fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangpublic class MediaSession2Test extends MediaSession2TestBase {
72fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final String TAG = "MediaSession2Test";
73fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
74fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MediaSession2 mSession;
75fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MockPlayer mPlayer;
76fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private MockPlaylistAgent mMockAgent;
77fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
78fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Before
79fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
80fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void setUp() throws Exception {
81fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.setUp();
82fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer = new MockPlayer(0);
83fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent = new MockPlaylistAgent();
84fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
85fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession = new MediaSession2.Builder(mContext)
86fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
87fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
88fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
89fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
90fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public SessionCommandGroup2 onConnect(MediaSession2 session,
91fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            ControllerInfo controller) {
92fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        if (Process.myUid() == controller.getUid()) {
93fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            return super.onConnect(session, controller);
94fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
95fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        return null;
96fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
97fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build();
98fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
99fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @After
101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void cleanUp() throws Exception {
103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.cleanUp();
104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.close();
105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBuilder() {
109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaSession2.Builder builder = new MediaSession2.Builder(mContext);
111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            builder.setPlayer(null);
113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            fail("null player shouldn't be allowed");
114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } catch (IllegalArgumentException e) {
115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // expected. pass-through
116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            builder.setId(null);
119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            fail("null id shouldn't be allowed");
120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } catch (IllegalArgumentException e) {
121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // expected. pass-through
122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayerStateChange() throws Exception {
127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
1284c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int targetState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext)
135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setPlayer(mPlayer)
136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, new SessionCallback() {
137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            @Override
138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            public void onPlayerStateChanged(MediaSession2 session,
1394c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                                    MediaPlayerInterface player, int state) {
140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                assertEquals(targetState, state);
141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                latchForSessionCallback.countDown();
142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }).build();
144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForControllerCallback = new CountDownLatch(1);
148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller =
149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                createController(mSession.getToken(), true, new ControllerCallback() {
150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
151fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onPlayerStateChanged(MediaController2 controllerOut, int state) {
152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(targetState, state);
153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForControllerCallback.countDown();
154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                });
156fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
157ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        mPlayer.notifyPlaybackState(targetState);
158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(targetState, controller.getPlayerState());
161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
164ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    public void testBufferingStateChange() throws Exception {
165ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        prepareLooper();
166ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        final List<MediaItem2> playlist = TestUtils.createPlaylist(5);
167ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon
168ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        final MediaItem2 targetItem = playlist.get(3);
1694c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int targetBufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
170ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
171ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        sHandler.postAndSync(new Runnable() {
172ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon            @Override
173ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon            public void run() {
174ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                mSession.close();
175ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                mMockAgent.setPlaylist(playlist, null);
176ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                mSession = new MediaSession2.Builder(mContext)
177ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        .setPlayer(mPlayer)
178ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        .setPlaylistAgent(mMockAgent)
179ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        .setSessionCallback(sHandlerExecutor, new SessionCallback() {
180ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                            @Override
181ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                            public void onBufferingStateChanged(MediaSession2 session,
1824c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                                    MediaPlayerInterface player, MediaItem2 item, int state) {
183ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                                assertEquals(targetItem, item);
184ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                                assertEquals(targetBufferingState, state);
185ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                                latchForSessionCallback.countDown();
186ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                            }
187ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        }).build();
188ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon            }
189ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        });
190ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon
191ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        final CountDownLatch latchForControllerCallback = new CountDownLatch(1);
192ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        final MediaController2 controller =
193ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                createController(mSession.getToken(), true, new ControllerCallback() {
194ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                    @Override
195ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                    public void onBufferingStateChanged(MediaController2 controller,
196ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                            MediaItem2 item, int state) {
197ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        assertEquals(targetItem, item);
198ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        assertEquals(targetBufferingState, state);
199ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                        latchForControllerCallback.countDown();
200ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                    }
201ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon                });
202ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon
2031a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        mPlayer.notifyBufferingStateChanged(targetItem.getDataSourceDesc(), targetBufferingState);
204ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
205ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
206ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        assertEquals(targetBufferingState, controller.getBufferingState());
207ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    }
208ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon
209ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    @Test
2101a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim    public void testSeekCompleted() throws Exception {
2111a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        prepareLooper();
2121a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        final long testPosition = 1001;
2131a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        final CountDownLatch latch = new CountDownLatch(1);
2141a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        final SessionCallback callback = new SessionCallback() {
2151a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim            @Override
2164c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onSeekCompleted(
2174c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                    MediaSession2 session, MediaPlayerInterface mpb, long position) {
2181a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                assertEquals(mPlayer, mpb);
2191a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                assertEquals(testPosition, position);
2201a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                latch.countDown();
2211a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim            }
2221a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        };
2231a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim
2241a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        try (MediaSession2 session = new MediaSession2.Builder(mContext)
2251a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                .setPlayer(mPlayer)
2261a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                .setPlaylistAgent(mMockAgent)
2271a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                .setId("testSeekCompleted")
2281a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim                .setSessionCallback(sHandlerExecutor, callback).build()) {
2291a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim            mPlayer.mCurrentPosition = testPosition;
2301a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim            mPlayer.notifySeekCompleted(testPosition);
2311a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
2321a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim        }
2331a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim    }
2341a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim
2351a125123e09a1f0e2991b1fce907970d8993667eJaewan Kim    @Test
236fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testCurrentDataSourceChanged() throws Exception {
237fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
239fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
240fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
241fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
242fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
2436664528b732914ee5082937971b11ae20acda3b7Jaewan Kim        final CountDownLatch latchForSessionCallback = new CountDownLatch(2);
244fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
245fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
247fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testCurrentDataSourceChanged")
248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
249fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
250fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onCurrentMediaItemChanged(MediaSession2 session,
2514c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                            MediaPlayerInterface player, MediaItem2 item) {
2526664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                        switch ((int) latchForSessionCallback.getCount()) {
2536664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                            case 2:
2546664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                assertEquals(currentItem, item);
2556664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                break;
2566664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                            case 1:
2576664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                assertNull(item);
2586664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                        }
259fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
260fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
261fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
262fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2636664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            final CountDownLatch latchForControllerCallback = new CountDownLatch(2);
2643a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon            final MediaController2 controller =
2653a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                    createController(mSession.getToken(), true, new ControllerCallback() {
2663a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                        @Override
2673a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                        public void onCurrentMediaItemChanged(MediaController2 controller,
2683a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                                MediaItem2 item) {
2696664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                            switch ((int) latchForControllerCallback.getCount()) {
2706664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                case 2:
2716664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                    assertEquals(currentItem, item);
2726664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                    break;
2736664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                case 1:
2746664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                                    assertNull(item);
2756664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                            }
2763a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                            latchForControllerCallback.countDown();
2773a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                        }
2783a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon                    });
2793a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon
2806664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            // Player notifies with the unknown dsd. Should be ignored.
2816664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            mPlayer.notifyCurrentDataSourceChanged(TestUtils.createMediaItemWithMetadata()
2826664528b732914ee5082937971b11ae20acda3b7Jaewan Kim                    .getDataSourceDesc());
2836664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            // Known DSD should be notified through the onCurrentMediaItemChanged.
284fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyCurrentDataSourceChanged(currentItem.getDataSourceDesc());
2856664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            // Null DSD becomes null MediaItem2.
2866664528b732914ee5082937971b11ae20acda3b7Jaewan Kim            mPlayer.notifyCurrentDataSourceChanged(null);
287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
2883a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon            assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
290fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
292fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
293fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testMediaPrepared() throws Exception {
294fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
298fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
302fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
303fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
304fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
305fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testMediaPrepared")
306fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
307fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
3084c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                    public void onMediaPrepared(MediaSession2 session, MediaPlayerInterface player,
309fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            MediaItem2 itemOut) {
310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertSame(currentItem, itemOut);
311fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
312fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
314fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
315fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyMediaPrepared(currentItem.getDataSourceDesc());
316fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
317fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO(jaewan): Test that controllers are also notified. (b/74505936)
318fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
320fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
321fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
322fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBufferingStateChanged() throws Exception {
323fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
324fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int listSize = 5;
325fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(listSize);
326fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
327fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
328fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 currentItem = list.get(3);
3294c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int buffState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_COMPLETE;
330fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
331fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
332fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
333fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
334fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
335fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testBufferingStateChanged")
336fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
337fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
338fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onBufferingStateChanged(MediaSession2 session,
3394c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                            MediaPlayerInterface player, MediaItem2 itemOut, int stateOut) {
340fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertSame(currentItem, itemOut);
341fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(buffState, stateOut);
342fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latchForSessionCallback.countDown();
343fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
344fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
345fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
346fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.notifyBufferingStateChanged(currentItem.getDataSourceDesc(), buffState);
347fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
348fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO(jaewan): Test that controllers are also notified. (b/74505936)
349fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
350fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
351fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
352e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    /**
353e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon     * This also tests {@link ControllerCallback#onPlaybackSpeedChanged(MediaController2, float)}
354e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon     * and {@link MediaController2#getPlaybackSpeed()}.
355e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon     */
356e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    @Test
357e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    public void testPlaybackSpeedChanged() throws Exception {
358e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        prepareLooper();
359e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        final float speed = 1.5f;
360e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        mPlayer.setPlaybackSpeed(speed);
361e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
362e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        final CountDownLatch latchForSessionCallback = new CountDownLatch(1);
363e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        try (MediaSession2 session = new MediaSession2.Builder(mContext)
364e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                .setPlayer(mPlayer)
365e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                .setId("testPlaybackSpeedChanged")
366e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
367e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                    @Override
368e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                    public void onPlaybackSpeedChanged(MediaSession2 session,
3694c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                            MediaPlayerInterface player, float speedOut) {
370e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                        assertEquals(speed, speedOut, 0.0f);
371e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                        latchForSessionCallback.countDown();
372e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                    }
373e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                }).build()) {
374e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
375e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            final CountDownLatch latchForControllerCallback = new CountDownLatch(1);
376e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            final MediaController2 controller =
377e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                    createController(mSession.getToken(), true, new ControllerCallback() {
378e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                        @Override
379e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                        public void onPlaybackSpeedChanged(MediaController2 controller,
380e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                                float speedOut) {
381e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                            assertEquals(speed, speedOut, 0.0f);
382e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                            latchForControllerCallback.countDown();
383e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                        }
384e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon                    });
385e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
386e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            mPlayer.notifyPlaybackSpeedChanged(speed);
387e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            assertTrue(latchForSessionCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
388e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            assertTrue(latchForControllerCallback.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
389e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon            assertEquals(speed, controller.getPlaybackSpeed(), 0.0f);
390e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        }
391e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    }
392e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
393fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
394fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testUpdatePlayer() throws Exception {
395fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
3964c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int targetState = MediaPlayerInterface.PLAYER_STATE_PLAYING;
397fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
398fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
399fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
400fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
401fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
402fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
403fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, new SessionCallback() {
404fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            @Override
405fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            public void onPlayerStateChanged(MediaSession2 session,
4064c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                                    MediaPlayerInterface player, int state) {
407fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                assertEquals(targetState, state);
408fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                latch.countDown();
409fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
410fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }).build();
411fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
412fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
413fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
414fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MockPlayer player = new MockPlayer(0);
415fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
416fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test if setPlayer doesn't crash with various situations.
417fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(mPlayer, null, null);
418fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(mPlayer, mSession.getPlayer());
419fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlaylistAgent agent = mSession.getPlaylistAgent();
420fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(agent);
421fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
422fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
423fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(player, mSession.getPlayer());
424fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(mSession.getPlaylistAgent());
425fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotEquals(agent, mSession.getPlaylistAgent());
426fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
4274c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        player.notifyPlaybackState(MediaPlayerInterface.PLAYER_STATE_PLAYING);
428fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
429fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
430fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
431fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
432c227e5c8c58de8656a0a31a1f48bf66e49c4a19dJaewan Kim    public void testUpdatePlayer_playbackInfo() throws Exception {
433fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
434fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MockPlayer player = new MockPlayer(0);
435fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final AudioAttributesCompat attrs = new AudioAttributesCompat.Builder()
436fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setContentType(CONTENT_TYPE_MUSIC)
437fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build();
438fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        player.setAudioAttributes(attrs);
439fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
440fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int maxVolume = 100;
441fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int currentVolume = 23;
442f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon        final int volumeControlType = VOLUME_CONTROL_ABSOLUTE;
443f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon        VolumeProviderCompat volumeProvider = new VolumeProviderCompat(
444f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon                volumeControlType, maxVolume, currentVolume) { };
445fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
446fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
447fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
448fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
449fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onPlaybackInfoChanged(MediaController2 controller, PlaybackInfo info) {
450fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Assert.assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
451fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(attrs, info.getAudioAttributes());
452fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(volumeControlType, info.getPlaybackType());
453fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(maxVolume, info.getMaxVolume());
454fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(currentVolume, info.getCurrentVolume());
455fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
456fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
457fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
458fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
460fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
461fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
462fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        PlaybackInfo info = controller.getPlaybackInfo();
463fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(info);
464fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(PlaybackInfo.PLAYBACK_TYPE_LOCAL, info.getPlaybackType());
465fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(attrs, info.getAudioAttributes());
466fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
467f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon
468f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon        int localVolumeControlType = VOLUME_CONTROL_ABSOLUTE;
469f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon        if (Build.VERSION.SDK_INT >= 21 && manager.isVolumeFixed()) {
470f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon            localVolumeControlType = VOLUME_CONTROL_FIXED;
471f66f34b424baf93d223bb905184b5b6e1d086c5dHyundo Moon        }
472fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(localVolumeControlType, info.getControlType());
473fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), info.getMaxVolume());
474fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(manager.getStreamVolume(AudioManager.STREAM_MUSIC), info.getCurrentVolume());
475fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
476fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, volumeProvider);
477fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
478fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
479fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        info = controller.getPlaybackInfo();
480fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(info);
481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
482fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(attrs, info.getAudioAttributes());
483fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(volumeControlType, info.getControlType());
484fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(maxVolume, info.getMaxVolume());
485fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(currentVolume, info.getCurrentVolume());
486fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
487fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
488fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
489fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlay() throws Exception {
490fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
491fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.play();
492fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPlayCalled);
493fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
494fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
495fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
496fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPause() throws Exception {
497fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
498fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.pause();
499fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPauseCalled);
500fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
501fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
502fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
503fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testReset() throws Exception {
504fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
505fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.reset();
506fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mResetCalled);
507fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
508fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
509fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
510fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPrepare() throws Exception {
511fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
512fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.prepare();
513fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPrepareCalled);
514fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
515fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
516fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
517fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSeekTo() throws Exception {
518fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
519fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long pos = 1004L;
520fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.seekTo(pos);
521fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mSeekToCalled);
522fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(pos, mPlayer.mSeekPosition);
523fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
524fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
525fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
526fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    public void testGetDuration() throws Exception {
527fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        prepareLooper();
528fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final long testDuration = 9999;
529fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        mPlayer.mDuration = testDuration;
530fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        assertEquals(testDuration, mSession.getDuration());
531fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    }
532fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim
533fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    @Test
534fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    public void testSessionCallback_onMediaPrepared() throws Exception {
535fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        prepareLooper();
536fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final long testDuration = 9999;
537fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final List<MediaItem2> list = TestUtils.createPlaylist(2);
538fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final MediaItem2 testItem = list.get(1);
539fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final CountDownLatch latch = new CountDownLatch(1);
540fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim
541fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        mPlayer.mDuration = testDuration;
542fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        mMockAgent.setPlaylist(list, null);
543fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        mMockAgent.mCurrentMediaItem = testItem;
544fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim
545fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        final SessionCallback sessionCallback = new SessionCallback() {
546fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim            @Override
5474c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onMediaPrepared(MediaSession2 session, MediaPlayerInterface player,
548fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                    MediaItem2 item) {
549fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                assertEquals(testItem, item);
550fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                assertEquals(testDuration,
551fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                        item.getMetadata().getLong(MediaMetadata2.METADATA_KEY_DURATION));
552fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                latch.countDown();
553fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim            }
554fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        };
555fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        try (MediaSession2 session = new MediaSession2.Builder(mContext)
556fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                .setPlayer(mPlayer)
557fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                .setPlaylistAgent(mMockAgent)
558fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                .setId("testSessionCallback")
559fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                .setSessionCallback(sHandlerExecutor, sessionCallback)
560fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim                .build()) {
561fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim            mPlayer.notifyMediaPrepared(testItem.getDataSourceDesc());
562fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
563fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim        }
564fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    }
565fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim
566fcda4bbadd0246854701e02e1752f4994f2bc474Jaewan Kim    @Test
567e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    public void testSetPlaybackSpeed() throws Exception {
568e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        prepareLooper();
569e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        final float speed = 1.5f;
570e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        mSession.setPlaybackSpeed(speed);
571e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        assertTrue(mPlayer.mSetPlaybackSpeedCalled);
572e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        assertEquals(speed, mPlayer.mPlaybackSpeed, 0.0f);
573e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    }
574e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
575e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    @Test
576e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    public void testGetPlaybackSpeed() throws Exception {
577e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        prepareLooper();
578e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        final float speed = 1.5f;
579e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        mPlayer.setPlaybackSpeed(speed);
580e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon        assertEquals(speed, mSession.getPlaybackSpeed(), 0.0f);
581e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    }
582e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon
583e18fafc56c49f683278d91e16a7246c7b1e01badHyundo Moon    @Test
5843a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon    public void testGetCurrentMediaItem() {
5853a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon        prepareLooper();
5863a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon        MediaItem2 item = TestUtils.createMediaItemWithMetadata();
5873a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon        mMockAgent.mCurrentMediaItem = item;
5883a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon        assertEquals(item, mSession.getCurrentMediaItem());
5893a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon    }
5903a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon
5913a151f1283d08b40c12e4a17903ba421f23c4342Hyundo Moon    @Test
592fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToPreviousItem() {
593fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
594fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToPreviousItem();
595fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToPreviousItemCalled);
596fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
597fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
598fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
599fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToNextItem() throws Exception {
600fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
601fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToNextItem();
602fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToNextItemCalled);
603fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
604fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
605fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
606fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSkipToPlaylistItem() throws Exception {
607fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
608fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
609fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.skipToPlaylistItem(testMediaItem);
610fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSkipToPlaylistItemCalled);
611fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
612fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
613fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
614fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
615fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlayerState() {
616fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
6174c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int state = MediaPlayerInterface.PLAYER_STATE_PLAYING;
618fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mLastPlayerState = state;
619fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(state, mSession.getPlayerState());
620fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
621fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
622fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
623ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    public void testGetBufferingState() {
624ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        prepareLooper();
6254c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        final int bufferingState = MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE;
626ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        mPlayer.mLastBufferingState = bufferingState;
627ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon        assertEquals(bufferingState, mSession.getBufferingState());
628ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    }
629ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon
630ebc904f04b5f4c011ec791b1b0e94660ac02fdbaHyundo Moon    @Test
631fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPosition() {
632fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
633fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long position = 150000;
634fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mCurrentPosition = position;
635fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(position, mSession.getCurrentPosition());
636fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
637fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
638fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
639fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetBufferedPosition() {
640fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
641fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long bufferedPosition = 900000;
642fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.mBufferedPosition = bufferedPosition;
643fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(bufferedPosition, mSession.getBufferedPosition());
644fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
645fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
646fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
647fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetPlaylist() {
648fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
649fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
650fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setPlaylist(list, null);
651fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetPlaylistCalled);
652fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(list, mMockAgent.mPlaylist);
653fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNull(mMockAgent.mMetadata);
654fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
655fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
656fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
657fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlaylist() {
658fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
659fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
660fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.mPlaylist = list;
661fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(list, mSession.getPlaylist());
662fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
663fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
664fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
665fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testUpdatePlaylistMetadata() {
666fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
667fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaMetadata2 testMetadata = TestUtils.createMetadata();
668fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlaylistMetadata(testMetadata);
669fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mUpdatePlaylistMetadataCalled);
670fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMetadata, mMockAgent.mMetadata);
671fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
672fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
673fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
674fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetPlaylistMetadata() {
675fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
676fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaMetadata2 testMetadata = TestUtils.createMetadata();
677fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.mMetadata = testMetadata;
678fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testMetadata, mSession.getPlaylistMetadata());
679fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
680fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
681fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
682fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSessionCallback_onPlaylistChanged() throws InterruptedException {
683fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
684fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<MediaItem2> list = TestUtils.createPlaylist(2);
685fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
686fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setPlaylist(list, null);
687fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
688fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
689fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
690fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onPlaylistChanged(MediaSession2 session, MediaPlaylistAgent playlistAgent,
691fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    List<MediaItem2> playlist, MediaMetadata2 metadata) {
692fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
693fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(list, playlist);
694fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNull(metadata);
695fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
696fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
697fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
698fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
699fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
700fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
701fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testSessionCallback")
702fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
703fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
704fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyPlaylistChanged();
705fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
706fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
707fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
708fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
709fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
710fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testAddPlaylistItem() {
711fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
712fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testIndex = 12;
713fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
714fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.addPlaylistItem(testIndex, testMediaItem);
715fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mAddPlaylistItemCalled);
716fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testIndex, mMockAgent.mIndex);
717fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
718fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
719fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
720fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
721fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRemovePlaylistItem() {
722fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
723fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
724fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.removePlaylistItem(testMediaItem);
725fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mRemovePlaylistItemCalled);
726fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
727fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
728fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
729fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
730fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testReplacePlaylistItem() throws InterruptedException {
731fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
732fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testIndex = 12;
733fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaItem2 testMediaItem = TestUtils.createMediaItemWithMetadata();
734fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.replacePlaylistItem(testIndex, testMediaItem);
735fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mReplacePlaylistItemCalled);
736fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testIndex, mMockAgent.mIndex);
737fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertSame(testMediaItem, mMockAgent.mItem);
738fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
739fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
740fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
741fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * This also tests {@link SessionCallback#onShuffleModeChanged}
742fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
743fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
744fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetShuffleMode() throws InterruptedException {
745fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
746fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
747fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setShuffleMode(testShuffleMode);
748fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
749fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
750fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
751fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
752fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onShuffleModeChanged(MediaSession2 session,
753fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    MediaPlaylistAgent playlistAgent, int shuffleMode) {
754fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
755fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testShuffleMode, shuffleMode);
756fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
757fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
758fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
759fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
760fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
761fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
762fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testGetShuffleMode")
763fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
764fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
765fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyShuffleModeChanged();
766fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
767fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
768fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
769fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
770fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
771fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetShuffleMode() {
772fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
773fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testShuffleMode = MediaPlaylistAgent.SHUFFLE_MODE_GROUP;
774fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setShuffleMode(testShuffleMode);
775fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetShuffleModeCalled);
776fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testShuffleMode, mMockAgent.mShuffleMode);
777fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
778fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
779fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
780fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * This also tests {@link SessionCallback#onShuffleModeChanged}
781fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
782fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
783fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetRepeatMode() throws InterruptedException {
784fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
785fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
786fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mMockAgent.setRepeatMode(testRepeatMode);
787fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
788fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
789fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
790fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
791fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onRepeatModeChanged(MediaSession2 session, MediaPlaylistAgent playlistAgent,
792fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    int repeatMode) {
793fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(mMockAgent, playlistAgent);
794fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testRepeatMode, repeatMode);
795fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
796fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
797fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
798fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
799fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
800fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlaylistAgent(mMockAgent)
801fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testGetRepeatMode")
802fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
803fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
804fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mMockAgent.notifyRepeatModeChanged();
805fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
806fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
807fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
808fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
809fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
810fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetRepeatMode() {
811fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
812fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int testRepeatMode = MediaPlaylistAgent.REPEAT_MODE_GROUP;
813fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setRepeatMode(testRepeatMode);
814fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mMockAgent.mSetRepeatModeCalled);
815fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(testRepeatMode, mMockAgent.mRepeatMode);
816fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
817fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
818fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // TODO(jaewan): Revisit
819fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Ignore
820fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
821fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testBadPlayer() throws InterruptedException {
822fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
823fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Add equivalent tests again
824fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(4); // expected call + 1
825fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final BadPlayer player = new BadPlayer(0);
826fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
827fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(player, null, null);
828fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.updatePlayer(mPlayer, null, null);
8294c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        player.notifyPlaybackState(MediaPlayerInterface.PLAYER_STATE_PAUSED);
830fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
831fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
832fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
833fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // This bad player will keep push events to the listener that is previously
834fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // registered by session.setPlayer().
835fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static class BadPlayer extends MockPlayer {
836fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        BadPlayer(int count) {
837fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            super(count);
838fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
839fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
840fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
841fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public void unregisterPlayerEventCallback(
8424c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                @NonNull MediaPlayerInterface.PlayerEventCallback listener) {
843fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // No-op.
844fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
845fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
846fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
847fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
848fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnCommandCallback() throws InterruptedException {
849fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
850fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MockOnCommandCallback callback = new MockOnCommandCallback();
851fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
852fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
853fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
854fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
855fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mPlayer = new MockPlayer(1);
856fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
857fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, callback).build();
858fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
859fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
860fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaController2 controller = createController(mSession.getToken());
861fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        controller.pause();
862fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
863fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mPauseCalled);
864fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(1, callback.commands.size());
865fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE,
866fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                (long) callback.commands.get(0).getCommandCode());
867fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
868fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        controller.play();
869fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
870fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.mPlayCalled);
871fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mPlayer.mPauseCalled);
872fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(2, callback.commands.size());
873fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY,
874fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                (long) callback.commands.get(1).getCommandCode());
875fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
876fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
877fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
878fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnConnectCallback() throws InterruptedException {
879fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
880fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MockOnConnectCallback sessionCallback = new MockOnConnectCallback();
881fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sHandler.postAndSync(new Runnable() {
882fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
883fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void run() {
884fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
885fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
886fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setSessionCallback(sHandlerExecutor, sessionCallback).build();
887fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
888fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        });
889fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaController2 controller = createController(mSession.getToken(), false, null);
890fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controller);
891fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        waitForConnect(controller, false);
892fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        waitForDisconnect(controller, true);
893fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
894fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
895fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
896fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testOnDisconnectCallback() throws InterruptedException {
897fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
898fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
899fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
900fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
901fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testOnDisconnectCallback")
902fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, new SessionCallback() {
903fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
904fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onDisconnected(MediaSession2 session,
905fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            ControllerInfo controller) {
906fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(Process.myUid(), controller.getUid());
907fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        latch.countDown();
908fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
909fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }).build()) {
910fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaController2 controller = createController(session.getToken());
911fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            controller.close();
912fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
913fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
914fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
915fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
916fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
917fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetCustomLayout() throws InterruptedException {
918fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
919fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final List<CommandButton> buttons = new ArrayList<>();
920fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        buttons.add(new CommandButton.Builder()
921fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY))
922fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDisplayName("button").build());
923fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
924fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCallback sessionCallback = new SessionCallback() {
925fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
926fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public SessionCommandGroup2 onConnect(MediaSession2 session,
927fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    ControllerInfo controller) {
928fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (mContext.getPackageName().equals(controller.getPackageName())) {
929fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mSession.setCustomLayout(controller, buttons);
930fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
931fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return super.onConnect(session, controller);
932fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
933fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
934fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
935fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try (MediaSession2 session = new MediaSession2.Builder(mContext)
936fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setPlayer(mPlayer)
937fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setId("testSetCustomLayout")
938fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setSessionCallback(sHandlerExecutor, sessionCallback)
939fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build()) {
940fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (mSession != null) {
941fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession.close();
942fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mSession = session;
943fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
944fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final ControllerCallback callback = new ControllerCallback() {
945fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                @Override
946fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                public void onCustomLayoutChanged(MediaController2 controller2,
947fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        List<CommandButton> layout) {
948fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    assertEquals(layout.size(), buttons.size());
949fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    for (int i = 0; i < layout.size(); i++) {
950fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(layout.get(i).getCommand(), buttons.get(i).getCommand());
951fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        assertEquals(layout.get(i).getDisplayName(),
952fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                buttons.get(i).getDisplayName());
953fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
954fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    latch.countDown();
955fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
956fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            };
957fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final MediaController2 controller =
958fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    createController(session.getToken(), true, callback);
959fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
960fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
961fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
962fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
963fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
964fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetAllowedCommands() throws InterruptedException {
965fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
966fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCommandGroup2 commands = new SessionCommandGroup2();
967fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY));
968fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE));
969fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        commands.addCommand(new SessionCommand2(SessionCommand2.COMMAND_CODE_PLAYBACK_RESET));
970fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
971fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
972fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
973fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
974fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onAllowedCommandsChanged(MediaController2 controller,
975fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    SessionCommandGroup2 commandsOut) {
976fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNotNull(commandsOut);
977fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Set<SessionCommand2> expected = commands.getCommands();
978fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Set<SessionCommand2> actual = commandsOut.getCommands();
979fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
980fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNotNull(actual);
981fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(expected.size(), actual.size());
982fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                for (SessionCommand2 command : expected) {
983fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    assertTrue(actual.contains(command));
984fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
985fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
986fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
987fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
988fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
989fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
990fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ControllerInfo controllerInfo = getTestControllerInfo();
991fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllerInfo);
992fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
993fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.setAllowedCommands(controllerInfo, commands);
994fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
995fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
996fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
997fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
998fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSendCustomCommand() throws InterruptedException {
999fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
1000fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final SessionCommand2 testCommand = new SessionCommand2(
1001fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
1002fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Bundle testArgs = new Bundle();
1003fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testArgs.putString("args", "testSendCustomAction");
1004fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1005fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(2);
1006fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
1007fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1008fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCustomCommand(MediaController2 controller, SessionCommand2 command,
1009fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    Bundle args, ResultReceiver receiver) {
1010fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(testCommand, command);
1011fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(TestUtils.equals(testArgs, args));
1012fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertNull(receiver);
1013fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
1014fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1015fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1016fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller =
1017fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                createController(mSession.getToken(), true, callback);
1018fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test with multiple controllers
1019fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.sendCustomCommand(testCommand, testArgs);
1020fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1021fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ControllerInfo controllerInfo = getTestControllerInfo();
1022fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllerInfo);
1023fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test receivers as well.
1024fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.sendCustomCommand(controllerInfo, testCommand, testArgs, null);
1025fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
1026fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1027fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1028fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1029fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testNotifyError() throws InterruptedException {
1030fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        prepareLooper();
1031fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int errorCode = MediaSession2.ERROR_CODE_NOT_AVAILABLE_IN_REGION;
1032fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Bundle extras = new Bundle();
1033fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        extras.putString("args", "testNotifyError");
1034fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1035fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch latch = new CountDownLatch(1);
1036fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final ControllerCallback callback = new ControllerCallback() {
1037fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1038fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onError(MediaController2 controller, int errorCodeOut, Bundle extrasOut) {
1039fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(errorCode, errorCodeOut);
1040fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(TestUtils.equals(extras, extrasOut));
1041fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                latch.countDown();
1042fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1043fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1044fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final MediaController2 controller = createController(mSession.getToken(), true, callback);
1045fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO(jaewan): Test with multiple controllers
1046fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSession.notifyError(errorCode, extras);
1047fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
1048fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1049fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1050fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim    @Test
1051fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim    public void testNotifyRoutesInfoChanged() throws InterruptedException {
1052fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        prepareLooper();
1053fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        final CountDownLatch latch = new CountDownLatch(1);
1054fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        final ControllerCallback callback = new ControllerCallback() {
1055fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim            @Override
1056fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim            public void onRoutesInfoChanged(@NonNull MediaController2 controller,
1057fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim                    @Nullable List<Bundle> routes) {
1058fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim                assertNull(routes);
1059fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim                latch.countDown();
1060fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim            }
1061fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        };
1062fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        final MediaController2 controller = createController(mSession.getToken(), true, callback);
1063fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        ControllerInfo controllerInfo = getTestControllerInfo();
1064fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        mSession.notifyRoutesInfoChanged(controllerInfo, null);
1065fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
1066fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim    }
1067fa1b27e361831b01f2d97d816f48c39ccf0ff539Sungsoo Lim
1068fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private ControllerInfo getTestControllerInfo() {
1069fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        List<ControllerInfo> controllers = mSession.getConnectedControllers();
1070fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(controllers);
1071fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < controllers.size(); i++) {
1072fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (Process.myUid() == controllers.get(i).getUid()) {
1073fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return controllers.get(i);
1074fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1075fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1076fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        fail("Failed to get test controller info");
1077fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return null;
1078fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1079fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1080fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public class MockOnConnectCallback extends SessionCallback {
1081fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
1082fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public SessionCommandGroup2 onConnect(MediaSession2 session,
1083fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ControllerInfo controllerInfo) {
1084fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (Process.myUid() != controllerInfo.getUid()) {
1085fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return null;
1086fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1087fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
1088fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(Process.myUid(), controllerInfo.getUid());
1089fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(controllerInfo.isTrusted());
1090fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Reject all
1091fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return null;
1092fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1093fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1094fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1095fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public class MockOnCommandCallback extends SessionCallback {
1096fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public final ArrayList<SessionCommand2> commands = new ArrayList<>();
1097fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1098fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        @Override
1099fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        public boolean onCommandRequest(MediaSession2 session, ControllerInfo controllerInfo,
1100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                SessionCommand2 command) {
1101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
1102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(Process.myUid(), controllerInfo.getUid());
1103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(controllerInfo.isTrusted());
1104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            commands.add(command);
1105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (command.getCommandCode() == SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE) {
1106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                return false;
1107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return true;
1109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static void assertMediaItemListEquals(List<MediaItem2> a, List<MediaItem2> b) {
1113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (a == null || b == null) {
1114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(a, b);
1115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(a.size(), b.size());
1117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < a.size(); i++) {
1119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaItem2 aItem = a.get(i);
1120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaItem2 bItem = b.get(i);
1121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (aItem == null || bItem == null) {
1123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(aItem, bItem);
1124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                continue;
1125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(aItem.getMediaId(), bItem.getMediaId());
1128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(aItem.getFlags(), bItem.getFlags());
1129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            TestUtils.equals(aItem.getMetadata().toBundle(), bItem.getMetadata().toBundle());
1130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Note: Here it does not check whether DataSourceDesc are equal,
1132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // since there DataSourceDec is not comparable.
1133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang}
1136