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 Kangpackage androidx.media;
17fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
18fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertEquals;
19fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertFalse;
20fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertNotNull;
21fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.assertTrue;
22fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport static org.junit.Assert.fail;
23fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
24fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.pm.PackageManager;
25fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.content.res.AssetFileDescriptor;
26fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.hardware.Camera;
27fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.AudioManager;
28fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.MediaMetadataRetriever;
29fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.MediaRecorder;
30fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.MediaTimestamp;
31fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.PlaybackParams;
327e23d54808f79ce964686e7551765da17bc3f585Dongwon Kangimport android.media.SubtitleData;
33fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.SyncParams;
34fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.audiofx.AudioEffect;
35fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.media.audiofx.Visualizer;
36fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.net.Uri;
37fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Build;
38fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.os.Environment;
39fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.LargeTest;
4054e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kangimport android.support.test.filters.MediumTest;
41fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.filters.SdkSuppress;
4298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kangimport android.support.test.filters.SmallTest;
43fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.support.test.runner.AndroidJUnit4;
44fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport android.util.Log;
45fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
464c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kangimport androidx.media.MediaPlayerInterface.PlayerEventCallback;
47fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport androidx.media.test.R;
48fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
49ddf1463e87704b61b080c7b4e8f2b5f43173263dDongwon Kangimport org.junit.After;
50ddf1463e87704b61b080c7b4e8f2b5f43173263dDongwon Kangimport org.junit.Before;
51fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.Test;
52fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport org.junit.runner.RunWith;
53fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
54fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.io.BufferedReader;
55fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.io.File;
5698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kangimport java.io.IOException;
57fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.io.InputStream;
58fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.io.InputStreamReader;
5998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kangimport java.util.ArrayDeque;
60fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.ArrayList;
61fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.List;
62fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.Vector;
637e23d54808f79ce964686e7551765da17bc3f585Dongwon Kangimport java.util.concurrent.BlockingDeque;
64fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangimport java.util.concurrent.CountDownLatch;
651666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kangimport java.util.concurrent.ExecutorService;
661666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kangimport java.util.concurrent.Executors;
677e23d54808f79ce964686e7551765da17bc3f585Dongwon Kangimport java.util.concurrent.LinkedBlockingDeque;
681666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kangimport java.util.concurrent.atomic.AtomicInteger;
691666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kangimport java.util.concurrent.atomic.AtomicReference;
70fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
71fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@RunWith(AndroidJUnit4.class)
72fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang@SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
73fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kangpublic class MediaPlayer2Test extends MediaPlayer2TestBase {
74fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
75fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final String LOG_TAG = "MediaPlayer2Test";
76fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
77fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final int  RECORDED_VIDEO_WIDTH  = 176;
78fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final int  RECORDED_VIDEO_HEIGHT = 144;
79fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final long RECORDED_DURATION_MS  = 3000;
80fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private static final float FLOAT_TOLERANCE = .0001f;
81fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
82fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private String mRecordedFilePath;
83fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private final Vector<Integer> mSubtitleTrackIndex = new Vector<>();
84fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private final Monitor mOnSubtitleDataCalled = new Monitor();
85fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private int mSelectedSubtitleIndex;
86fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
87fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private File mOutFile;
88fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private Camera mCamera;
89fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
90ddf1463e87704b61b080c7b4e8f2b5f43173263dDongwon Kang    @Before
91fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
9254e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    public void setUp() throws Throwable {
93fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.setUp();
94fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mRecordedFilePath = new File(Environment.getExternalStorageDirectory(),
95fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                "mediaplayer_record.out").getAbsolutePath();
96fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOutFile = new File(mRecordedFilePath);
97fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
98fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
99ddf1463e87704b61b080c7b4e8f2b5f43173263dDongwon Kang    @After
100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Override
101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void tearDown() throws Exception {
102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        super.tearDown();
103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (mOutFile != null && mOutFile.exists()) {
104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mOutFile.delete();
105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
10854e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
10954e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @MediumTest
110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayNullSourcePath() throws Exception {
111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onSetDataSourceCalled = new Monitor();
112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    assertTrue(status != MediaPlayer2.CALL_STATUS_NO_ERROR);
117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onSetDataSourceCalled.signal();
118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onSetDataSourceCalled.reset();
126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource((DataSourceDesc) null);
127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onSetDataSourceCalled.waitForSignal();
128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
13054e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
13154e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @LargeTest
132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayAudioFromDataURI() throws Exception {
133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int mp3Duration = 34909;
134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int tolerance = 70;
135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int seekDuration = 100;
136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // This is "R.raw.testmp3_2", base64-encoded.
138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.testmp3_3;
139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        InputStream is = mContext.getResources().openRawResource(resid);
141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        StringBuilder builder = new StringBuilder();
144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        builder.append("data:;base64,");
145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        builder.append(reader.readLine());
146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Uri uri = Uri.parse(builder.toString());
147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2 mp = createMediaPlayer2(mContext, uri);
149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPrepareCalled = new Monitor();
151fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPlayCalled = new Monitor();
152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onSeekToCalled = new Monitor();
153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onLoopCurrentCalled = new Monitor();
154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
156fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
157fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onPrepareCalled.signal();
159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
164fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
165fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onPlayCalled.signal();
166fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_LOOP_CURRENT) {
167fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onLoopCurrentCalled.signal();
168fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
169fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onSeekToCalled.signal();
170fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
171fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
172fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
173fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
174fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
175fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
176fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
177fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
178fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build();
179fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setAudioAttributes(attributes);
180fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1814c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
182fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
183fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
184fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
1854c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
186fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
187fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: what's API for checking loop state?
188fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(mp.isLooping());
189fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
190fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.reset();
191fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.loopCurrent(true);
192fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.waitForSignal();
193fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: what's API for checking loop state?
194fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(mp.isLooping());
195fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
196fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
197fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mp3Duration, mp.getDuration(), tolerance);
198fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            long pos = mp.getCurrentPosition();
199fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos >= 0);
200fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos < mp3Duration - seekDuration);
201fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
202fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.reset();
203fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.seekTo(pos + seekDuration, MediaPlayer2.SEEK_PREVIOUS_SYNC);
204fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.waitForSignal();
205fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(pos + seekDuration, mp.getCurrentPosition(), tolerance);
206fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
207fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // test pause and restart
208fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.pause();
209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
2104c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
211fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
212fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
213fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
2144c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
215fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
216fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // test stop and restart
217fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.reset();
218fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
219fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setDataSource(new DataSourceDesc.Builder()
220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setDataSource(mContext, uri)
221fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build());
222fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.reset();
223fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.prepare();
224fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.waitForSignal();
225fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2264c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
227fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
228fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
229fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
2304c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
231fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
232fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // waiting to complete
2334c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
234fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME);
235fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
236fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
237fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.close();
238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
239fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
240fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
24154e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
24254e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @LargeTest
243fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayAudio() throws Exception {
244fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.testmp3_2;
245fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int mp3Duration = 34909;
246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int tolerance = 70;
247fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int seekDuration = 100;
248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
249fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2 mp = createMediaPlayer2(mContext, resid);
250fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
251fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPrepareCalled = new Monitor();
252fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPlayCalled = new Monitor();
253fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onSeekToCalled = new Monitor();
254fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onLoopCurrentCalled = new Monitor();
255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
256fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
257fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
258fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
259fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onPrepareCalled.signal();
260fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
261fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
262fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
263fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
264fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
265fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
266fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onPlayCalled.signal();
267fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_LOOP_CURRENT) {
268fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onLoopCurrentCalled.signal();
269fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
270fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onSeekToCalled.signal();
271fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
272fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
273fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
274fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
275fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
276fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
277fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
278fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
279fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build();
280fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setAudioAttributes(attributes);
281fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2824c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
283fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
284fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
285fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
2864c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
288fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            //assertFalse(mp.isLooping());
289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.reset();
290fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.loopCurrent(true);
291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.waitForSignal();
292fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            //assertTrue(mp.isLooping());
293fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
294fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(mp3Duration, mp.getDuration(), tolerance);
295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            long pos = mp.getCurrentPosition();
296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos >= 0);
297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos < mp3Duration - seekDuration);
298fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.reset();
300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.seekTo(pos + seekDuration, MediaPlayer2.SEEK_PREVIOUS_SYNC);
301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.waitForSignal();
302fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(pos + seekDuration, mp.getCurrentPosition(), tolerance);
303fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
304fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // test pause and restart
305fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.pause();
306fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
3074c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
308fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
309fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
3114c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
312fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // test stop and restart
314fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.reset();
315fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
316fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setDataSource(new DataSourceDesc.Builder()
317fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength())
318fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build());
319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
320fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
321fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.reset();
322fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.prepare();
323fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.waitForSignal();
324fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            afd.close();
325fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
3264c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
327fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
328fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
329fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
3304c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
331fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
332fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // waiting to complete
3334c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
334fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME);
335fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
336fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } catch (Exception e) {
337fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throw e;
338fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
339fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.close();
340fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
341fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
342fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
343fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /*
344fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testConcurentPlayAudio() throws Exception {
345fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.test1m1s; // MP3 longer than 1m are usualy offloaded
346fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int tolerance = 70;
347fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
348fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        List<MediaPlayer2> mps = Stream.generate(() -> createMediaPlayer2(mContext, resid))
349fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                      .limit(5).collect(Collectors.toList());
350fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
351fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
352fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            for (MediaPlayer2 mp : mps) {
353fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Monitor onPlayCalled = new Monitor();
354fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Monitor onLoopCurrentCalled = new Monitor();
355fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                MediaPlayer2.MediaPlayer2EventCallback ecb =
356fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    new MediaPlayer2.MediaPlayer2EventCallback() {
357fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        @Override
358fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
359fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                int what, int status) {
360fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
361fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                onPlayCalled.signal();
362fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            } else if (what == MediaPlayer2.CALL_COMPLETED_LOOP_CURRENT) {
363fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                onLoopCurrentCalled.signal();
364fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
365fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
366fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    };
367fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.setMediaPlayer2EventCallback(mExecutor, ecb);
368fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
369fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                AudioAttributes attributes = new AudioAttributes.Builder()
370fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setInternalLegacyStreamType(AudioManager.STREAM_MUSIC)
371fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .build();
372fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.setAudioAttributes(attributes);
373fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
374fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertFalse(mp.isPlaying());
375fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                onPlayCalled.reset();
376fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.play();
377fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                onPlayCalled.waitForSignal();
378fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(mp.isPlaying());
379fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
380fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertFalse(mp.isLooping());
381fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                onLoopCurrentCalled.reset();
382fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.loopCurrent(true);
383fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                onLoopCurrentCalled.waitForSignal();
384fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(mp.isLooping());
385fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
386fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                long pos = mp.getCurrentPosition();
387fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertTrue(pos >= 0);
388fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
389fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME); // Delay each track to be able to ear them
390fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
391fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Check that all mp3 are playing concurrently here
392fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            for (MediaPlayer2 mp : mps) {
393fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                long pos = mp.getCurrentPosition();
394fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME);
395fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                assertEquals(pos + SLEEP_TIME, mp.getCurrentPosition(), tolerance);
396fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
397fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
398fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mps.forEach(MediaPlayer2::close);
399fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
400fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
401fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    */
402fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
40354e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
40454e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @LargeTest
405fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayAudioLooping() throws Exception {
406fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.testmp3;
407fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
408fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2 mp = createMediaPlayer2(mContext, resid);
409fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
410fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
411fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
412fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build();
413fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setAudioAttributes(attributes);
414fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.loopCurrent(true);
415fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final Monitor onCompletionCalled = new Monitor();
416fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            final Monitor onPlayCalled = new Monitor();
417fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaPlayer2.MediaPlayer2EventCallback ecb =
418fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    new MediaPlayer2.MediaPlayer2EventCallback() {
419fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        @Override
420fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd,
421fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                int what, int extra) {
42254e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang                            if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
42354e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang                                Log.i("@@@", "got oncompletion");
42454e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang                                onCompletionCalled.signal();
42554e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang                            }
426fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
427fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
428fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        @Override
429fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
430fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                int what, int status) {
431fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
432fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                onPlayCalled.signal();
433fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
434fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
435fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    };
436fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
437fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
4384c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertFalse(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
439fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.reset();
440fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
441fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPlayCalled.waitForSignal();
4424c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
443fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
444fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            long duration = mp.getDuration();
445fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(duration * 4); // allow for several loops
4464c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            assertTrue(mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
447fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals("wrong number of completion signals", 0,
448fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onCompletionCalled.getNumSignal());
449fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.loopCurrent(false);
450fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
451fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // wait for playback to finish
4524c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            while (mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
453fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME);
454fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
455fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals("wrong number of completion signals", 1,
456fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onCompletionCalled.getNumSignal());
457fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
458fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.close();
459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
460fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
461fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
46254e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
46354e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @LargeTest
464fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayMidi() throws Exception {
465fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.midi8sec;
466fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int midiDuration = 8000;
467fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int tolerance = 70;
468fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int seekDuration = 1000;
469fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
470fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2 mp = createMediaPlayer2(mContext, resid);
471fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
472fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPrepareCalled = new Monitor();
473fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onSeekToCalled = new Monitor();
474fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onLoopCurrentCalled = new Monitor();
475fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb =
476fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                new MediaPlayer2.MediaPlayer2EventCallback() {
477fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
478fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
479fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
480fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            onPrepareCalled.signal();
481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
482fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
483fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
484fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    @Override
485fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
486fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            int what, int status) {
487fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        if (what == MediaPlayer2.CALL_COMPLETED_LOOP_CURRENT) {
488fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            onLoopCurrentCalled.signal();
489fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        } else if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
490fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            onSeekToCalled.signal();
491fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
492fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
493fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                };
494fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mp.setMediaPlayer2EventCallback(mExecutor, ecb);
495fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
496fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
497fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
498fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
499fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build();
500fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setAudioAttributes(attributes);
501fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
502fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
503fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
504fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: what's API for checking loop state?
505fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(mp.isLooping());
506fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
507fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.reset();
508fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.loopCurrent(true);
509fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onLoopCurrentCalled.waitForSignal();
510fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: what's API for checking loop state?
511fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(mp.isLooping());
512fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
513fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
514fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(midiDuration, mp.getDuration(), tolerance);
515fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            long pos = mp.getCurrentPosition();
516fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos >= 0);
517fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(pos < midiDuration - seekDuration);
518fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
519fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.reset();
520fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.seekTo(pos + seekDuration, MediaPlayer2.SEEK_PREVIOUS_SYNC);
521fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onSeekToCalled.waitForSignal();
522fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(pos + seekDuration, mp.getCurrentPosition(), tolerance);
523fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
524fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // test stop and restart
525fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.reset();
526fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
527fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setDataSource(new DataSourceDesc.Builder()
528fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength())
529fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build());
530fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
531fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setMediaPlayer2EventCallback(mExecutor, ecb);
532fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.reset();
533fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.prepare();
534fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            onPrepareCalled.waitForSignal();
535fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            afd.close();
536fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
537fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
538fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
539fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
540fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
541fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.close();
542fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
543fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
544fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
545fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    static class OutputListener {
546fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int mSession;
547fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        AudioEffect mVc;
548fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Visualizer mVis;
549fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        byte [] mVisData;
550fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        boolean mSoundDetected;
551fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        OutputListener(int session) {
552fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mSession = session;
553fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: find out a public API for replacing AudioEffect contructor.
554fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // creating a volume controller on output mix ensures that ro.audio.silent mutes
555fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // audio after the effects and not before
556fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVc = new AudioEffect(
557fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    AudioEffect.EFFECT_TYPE_NULL,
558fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
559fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    0,
560fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    session);
561fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVc.setEnabled(true);
562fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
563fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVis = new Visualizer(session);
564fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int size = 256;
565fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int[] range = Visualizer.getCaptureSizeRange();
566fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (size < range[0]) {
567fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                size = range[0];
568fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
569fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (size > range[1]) {
570fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                size = range[1];
571fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
572fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(mVis.setCaptureSize(size) == Visualizer.SUCCESS);
573fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
574fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVis.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
575fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                @Override
576fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                public void onWaveFormDataCapture(Visualizer visualizer,
577fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        byte[] waveform, int samplingRate) {
578fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    if (!mSoundDetected) {
579fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        for (int i = 0; i < waveform.length; i++) {
580fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            // 8 bit unsigned PCM, zero level is at 128, which is -128 when
581fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            // seen as a signed byte
582fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            if (waveform[i] != -128) {
583fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                mSoundDetected = true;
584fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                                break;
585fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                            }
586fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        }
587fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
588fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
589fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
590fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                @Override
591fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
592fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
593fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }, 10000 /* milliHertz */, true /* PCM */, false /* FFT */);
594fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(mVis.setEnabled(true) == Visualizer.SUCCESS);
595fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
596fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
597fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        void reset() {
598fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mSoundDetected = false;
599fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
600fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
601fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        boolean heardSound() {
602fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return mSoundDetected;
603fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
604fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
605fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        void release() {
606fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVis.release();
607fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            /* FIXME: find out a public API for replacing AudioEffect contructor.
608fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mVc.release();
609fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            */
610fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
611fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
612fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
613fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayAudioTwice() throws Exception {
614fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
615fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.camera_click;
616fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
617fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2 mp = createMediaPlayer2(mContext, resid);
618fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
619fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
620fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
621fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    .build();
622fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.setAudioAttributes(attributes);
623fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
624fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            OutputListener listener = new OutputListener(mp.getAudioSessionId());
625fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
626fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
627fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse("noise heard before test started", listener.heardSound());
628fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
629fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
630fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
631fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse("player was still playing after " + SLEEP_TIME + " ms",
6324c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                    mp.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
633fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue("nothing heard while test ran", listener.heardSound());
634fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            listener.reset();
635fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.seekTo(0, MediaPlayer2.SEEK_PREVIOUS_SYNC);
636fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.play();
637fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
638fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue("nothing heard when sound was replayed", listener.heardSound());
639fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            listener.release();
640fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
641fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mp.close();
642fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
643fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
644fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
645fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
646fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
647fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlayVideo() throws Exception {
648fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(R.raw.testvideo, 352, 288);
649fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
650fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
651fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /**
652fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * Test for reseting a surface during video playback
653fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * After reseting, the video should continue playing
654fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     * from the time setDisplay() was called
655fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
656fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
657fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
658fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testVideoSurfaceResetting() throws Exception {
659fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int tolerance = 150;
660fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int audioLatencyTolerance = 1000;  /* covers audio path latency variability */
661fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int seekPos = 4760;  // This is the I-frame position
662fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
663fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final CountDownLatch seekDone = new CountDownLatch(1);
664fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
665fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
666fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
667fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
668fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
669fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    seekDone.countDown();
670fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
671fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
672fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
673fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
674fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
675fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
676fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
677fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(R.raw.testvideo)) {
678fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip;
679fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
680fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playLoadedVideo(352, 288, -1);
681fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
682fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
683fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
684fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long posBefore = mPlayer.getCurrentPosition();
685fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder2().getSurface());
686fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long posAfter = mPlayer.getCurrentPosition();
687fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
688fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /* temporarily disable timestamp checking because MediaPlayer2 now seeks to I-frame
689fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         * position, instead of requested position. setDisplay invovles a seek operation
690fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         * internally.
691fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang         */
692fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
693fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // assertEquals(posAfter, posBefore, tolerance);
6944c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
695fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
696fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
697fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
698fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(seekPos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
699fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        seekDone.await();
700fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        posAfter = mPlayer.getCurrentPosition();
701fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(seekPos, posAfter, tolerance + audioLatencyTolerance);
702fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
703fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME / 2);
704fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        posBefore = mPlayer.getCurrentPosition();
705fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(null);
706fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        posAfter = mPlayer.getCurrentPosition();
707fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
708fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // assertEquals(posAfter, posBefore, tolerance);
7094c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
710fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
711fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
712fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
713fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        posBefore = mPlayer.getCurrentPosition();
714fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
715fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        posAfter = mPlayer.getCurrentPosition();
716fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
717fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: uncomment out line below when MediaPlayer2 can seek to requested position.
718fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // assertEquals(posAfter, posBefore, tolerance);
7194c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
720fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
721fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
722fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
723fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
724fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRecordedVideoPlayback0() throws Exception {
725fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testRecordedVideoPlaybackWithAngle(0);
726fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
727fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
728fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRecordedVideoPlayback90() throws Exception {
729fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testRecordedVideoPlaybackWithAngle(90);
730fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
731fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
732fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRecordedVideoPlayback180() throws Exception {
733fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testRecordedVideoPlaybackWithAngle(180);
734fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
735fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
736fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRecordedVideoPlayback270() throws Exception {
737fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        testRecordedVideoPlaybackWithAngle(270);
738fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
739fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
740fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private boolean hasCamera() {
741fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
742fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
743fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
744fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void testRecordedVideoPlaybackWithAngle(int angle) throws Exception {
745fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int width = RECORDED_VIDEO_WIDTH;
746fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int height = RECORDED_VIDEO_HEIGHT;
747fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final String file = mRecordedFilePath;
748fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long durationMs = RECORDED_DURATION_MS;
749fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
750fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!hasCamera()) {
751fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
752fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
753fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
754fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        boolean isSupported = false;
755fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mCamera = Camera.open(0);
756fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Camera.Parameters parameters = mCamera.getParameters();
757fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        List<Camera.Size> videoSizes = parameters.getSupportedVideoSizes();
758fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // getSupportedVideoSizes returns null when separate video/preview size
759fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // is not supported.
760fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (videoSizes == null) {
761fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            videoSizes = parameters.getSupportedPreviewSizes();
762fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
763fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (Camera.Size size : videoSizes) {
764fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (size.width == width && size.height == height) {
765fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                isSupported = true;
766fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                break;
767fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
768fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
769fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mCamera.release();
770fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mCamera = null;
771fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!isSupported) {
772fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            width = videoSizes.get(0).width;
773fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            height = videoSizes.get(0).height;
774fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
775fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        checkOrientation(angle);
776fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recordVideo(width, height, angle, file, durationMs);
777fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        checkDisplayedVideoSize(width, height, angle, file);
778fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        checkVideoRotationAngle(angle, file);
779fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
780fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
781fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void checkOrientation(int angle) throws Exception {
782fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(angle >= 0);
783fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(angle < 360);
784fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue((angle % 90) == 0);
785fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
786fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
787fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void recordVideo(
788fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int w, int h, int angle, String file, long durationMs) throws Exception {
789fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
790fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaRecorder recorder = new MediaRecorder();
791fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
792fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
793fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
794fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
795fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
796fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setOutputFile(file);
797fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setOrientationHint(angle);
798fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setVideoSize(w, h);
799fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.setPreviewDisplay(mActivity.getSurfaceHolder2().getSurface());
800fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.prepare();
801fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.start();
802fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(durationMs);
803fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.stop();
804fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder.release();
805fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        recorder = null;
806fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
807fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
808fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void checkDisplayedVideoSize(
809fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int w, int h, int angle, String file) throws Exception {
810fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
811fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int displayWidth  = w;
812fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int displayHeight = h;
813fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if ((angle % 180) != 0) {
814fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            displayWidth  = h;
815fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            displayHeight = w;
816fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
817fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(file, displayWidth, displayHeight);
818fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
819fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
820fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void checkVideoRotationAngle(int angle, String file) {
821fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
822fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        retriever.setDataSource(file);
823fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        String rotation = retriever.extractMetadata(
824fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
825fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        retriever.release();
826fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        retriever = null;
827fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertNotNull(rotation);
828fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(Integer.parseInt(rotation), angle);
829fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
830fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
8319b0f90e4d7507b3dd19a89588e5896c162fab1d4Robert Shih    @Test
8329b0f90e4d7507b3dd19a89588e5896c162fab1d4Robert Shih    @LargeTest
8330dd387e02d036366c1731cc898f38b8d222133adRobert Shih    public void testSkipToNext() throws Exception {
8340dd387e02d036366c1731cc898f38b8d222133adRobert Shih        testPlaylist(true);
8350dd387e02d036366c1731cc898f38b8d222133adRobert Shih    }
8360dd387e02d036366c1731cc898f38b8d222133adRobert Shih
8370dd387e02d036366c1731cc898f38b8d222133adRobert Shih    @Test
8380dd387e02d036366c1731cc898f38b8d222133adRobert Shih    @LargeTest
839fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlaylist() throws Exception {
8400dd387e02d036366c1731cc898f38b8d222133adRobert Shih        testPlaylist(false);
8410dd387e02d036366c1731cc898f38b8d222133adRobert Shih    }
8420dd387e02d036366c1731cc898f38b8d222133adRobert Shih
8430dd387e02d036366c1731cc898f38b8d222133adRobert Shih    private void testPlaylist(boolean skip) throws Exception {
844fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(
845fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
846fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
847fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
848fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final DataSourceDesc dsd1 = createDataSourceDesc(
849fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz);
850fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final DataSourceDesc dsd2 = createDataSourceDesc(
851fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.testvideo);
852fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ArrayList<DataSourceDesc> nextDSDs = new ArrayList<DataSourceDesc>(2);
853fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        nextDSDs.add(dsd2);
854fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        nextDSDs.add(dsd1);
855fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
856fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setNextDataSources(nextDSDs);
857fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
858fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onCompletion1Called = new Monitor();
859fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onCompletion2Called = new Monitor();
860fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
861fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
862fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
863fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
864fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    Log.i(LOG_TAG, "testPlaylist: prepared dsd MediaId=" + dsd.getMediaId());
865fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
866fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
867fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    if (dsd == dsd1) {
868fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        onCompletion1Called.signal();
869fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    } else if (dsd == dsd2) {
870fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        onCompletion2Called.signal();
871fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    } else {
872fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        mOnCompletionCalled.signal();
873fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    }
874fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
875fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
876fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
877fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
878fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
879fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
880fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
881fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.reset();
882fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onCompletion1Called.reset();
883fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onCompletion2Called.reset();
884fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
885fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
886fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
887fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
888fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
889fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
890fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
8910dd387e02d036366c1731cc898f38b8d222133adRobert Shih        if (skip) {
8920dd387e02d036366c1731cc898f38b8d222133adRobert Shih            mPlayer.skipToNext();
8930dd387e02d036366c1731cc898f38b8d222133adRobert Shih            mPlayer.skipToNext();
8940dd387e02d036366c1731cc898f38b8d222133adRobert Shih        } else {
8950dd387e02d036366c1731cc898f38b8d222133adRobert Shih            mOnCompletionCalled.waitForSignal();
8960dd387e02d036366c1731cc898f38b8d222133adRobert Shih            onCompletion2Called.waitForSignal();
8970dd387e02d036366c1731cc898f38b8d222133adRobert Shih        }
898fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onCompletion1Called.waitForSignal();
8990dd387e02d036366c1731cc898f38b8d222133adRobert Shih        if (skip) {
9000dd387e02d036366c1731cc898f38b8d222133adRobert Shih            assertFalse("first dsd completed", mOnCompletionCalled.isSignalled());
9010dd387e02d036366c1731cc898f38b8d222133adRobert Shih            assertFalse("second dsd completed", onCompletion2Called.isSignalled());
9020dd387e02d036366c1731cc898f38b8d222133adRobert Shih        }
903fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
904fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
905fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
906fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
907fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // setPlaybackParams() with non-zero speed should NOT start playback.
908fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // TODO: enable this test when MediaPlayer2.setPlaybackParams() is fixed
909fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /*
910fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSetPlaybackParamsPositiveSpeed() throws Exception {
911fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(
912fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
913fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
914fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
915fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
916fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
917fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
918fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
919fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
920fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
921fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
922fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnCompletionCalled.signal();
923fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
924fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
925fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
926fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
927fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
928fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
929fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnSeekCompleteCalled.signal();
930fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
931fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
932fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
933fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
934fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
935fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
936fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
937fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.reset();
938fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDisplay(mActivity.getSurfaceHolder());
939fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
940fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
941fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
942fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
943fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
944fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.reset();
945fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(0, MediaPlayer2.SEEK_PREVIOUS_SYNC);
946fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.waitForSignal();
947fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
948fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final float playbackRate = 1.0f;
949fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
950fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int playTime = 2000;  // The testing clip is about 10 second long.
951fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
952fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 should be playing", mPlayer.isPlaying());
953fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(playTime);
954fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 should still be playing",
955fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mPlayer.getCurrentPosition() > 0);
956fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
957fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long duration = mPlayer.getDuration();
958fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.reset();
959fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(duration - 1000, MediaPlayer2.SEEK_PREVIOUS_SYNC);
960fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.waitForSignal();
961fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
962fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.waitForSignal();
963fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse("MediaPlayer2 should not be playing", mPlayer.isPlaying());
964fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long eosPosition = mPlayer.getCurrentPosition();
965fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
966fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
967fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 should be playing after EOS", mPlayer.isPlaying());
968fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(playTime);
969fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long position = mPlayer.getCurrentPosition();
970fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 should still be playing after EOS",
971fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                position > 0 && position < eosPosition);
972fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
973fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
974fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
975fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    */
976fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
977fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
978fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
979fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlaybackRate() throws Exception {
980fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int toleranceMs = 1000;
981fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(
982fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
983fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
984fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
985fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
986fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
987fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
988fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
989fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
990fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
991fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
992fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
993fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
994fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
995fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
996fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
997fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
998fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
999fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1000fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1001fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1002fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1003fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        SyncParams sync = new SyncParams().allowDefaults();
1004fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSyncParams(sync);
1005fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        sync = mPlayer.getSyncParams();
1006fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1007fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        float[] rates = { 0.25f, 0.5f, 1.0f, 2.0f };
1008fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (float playbackRate : rates) {
1009fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.seekTo(0, MediaPlayer2.SEEK_PREVIOUS_SYNC);
1010fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(1000);
1011fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int playTime = 4000;  // The testing clip is about 10 second long.
1012fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
1013fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.play();
1014fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(playTime);
1015fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            PlaybackParams pbp = mPlayer.getPlaybackParams();
1016fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertEquals(
1017fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    playbackRate, pbp.getSpeed(),
1018fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    FLOAT_TOLERANCE + playbackRate * sync.getTolerance());
1019fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue("MediaPlayer2 should still be playing",
10204c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                    mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1021fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1022fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            long playedMediaDurationMs = mPlayer.getCurrentPosition();
1023fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            int diff = Math.abs((int) (playedMediaDurationMs / playbackRate) - playTime);
1024fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (diff > toleranceMs) {
1025fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                fail("Media player had error in playback rate " + playbackRate
1026fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        + ", play time is " + playTime + " vs expected " + playedMediaDurationMs);
1027fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1028fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mPlayer.pause();
1029fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            pbp = mPlayer.getPlaybackParams();
1030fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // TODO: pause() should NOT change PlaybackParams.
1031fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // assertEquals(0.f, pbp.getSpeed(), FLOAT_TOLERANCE);
1032fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1033fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1034fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1035fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1036fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1037fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
1038fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testSeekModes() throws Exception {
1039fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // This clip has 2 I frames at 66687us and 4299687us.
1040fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(
1041fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz)) {
1042fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
1043fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1044fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1045fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1046fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1047fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1048fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1049fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1050fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1051fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1052fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1053fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1054fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1055fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
1056fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnSeekCompleteCalled.signal();
1057fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1058fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1059fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1060fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
1061fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
1062fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1063fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1064fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1065fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1066fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1067fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1068fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1069fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1070fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.reset();
1071fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1072fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1073fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long seekPosMs = 3000;
1074fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long timeToleranceMs = 100;
1075fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long syncTime1Ms = 67;
1076fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final long syncTime2Ms = 4300;
1077fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1078fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: tighten checking range. For now, ensure mediaplayer doesn't
1079fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // seek to previous sync or next sync.
1080fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long cp = runSeekMode(MediaPlayer2.SEEK_CLOSEST, seekPosMs);
1081fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 did not seek to closest position",
1082fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                cp > seekPosMs && cp < syncTime2Ms);
1083fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1084fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: tighten checking range. For now, ensure mediaplayer doesn't
1085fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // seek to closest position or next sync.
1086fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        cp = runSeekMode(MediaPlayer2.SEEK_PREVIOUS_SYNC, seekPosMs);
1087fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 did not seek to preivous sync position",
1088fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                cp < seekPosMs - timeToleranceMs);
1089fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1090fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: tighten checking range. For now, ensure mediaplayer doesn't
1091fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // seek to closest position or previous sync.
1092fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        cp = runSeekMode(MediaPlayer2.SEEK_NEXT_SYNC, seekPosMs);
1093fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 did not seek to next sync position",
1094fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                cp > syncTime2Ms - timeToleranceMs);
1095fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1096fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // TODO: tighten checking range. For now, ensure mediaplayer doesn't
1097fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // seek to closest position or previous sync.
1098fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        cp = runSeekMode(MediaPlayer2.SEEK_CLOSEST_SYNC, seekPosMs);
1099fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 did not seek to closest sync position",
1100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                cp > syncTime2Ms - timeToleranceMs);
1101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private long runSeekMode(int seekMode, long seekPosMs) throws Exception {
1106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int sleepIntervalMs = 100;
1107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int timeRemainedMs = 10000;  // total time for testing
1108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int timeToleranceMs = 100;
1109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(seekPosMs, seekMode);
1111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.waitForSignal();
1112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.reset();
1113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long cp = -seekPosMs;
1114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        while (timeRemainedMs > 0) {
1115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            cp = mPlayer.getCurrentPosition();
1116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Wait till MediaPlayer2 starts rendering since MediaPlayer2 caches
1117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // seek position as current position.
1118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (cp < seekPosMs - timeToleranceMs || cp > seekPosMs + timeToleranceMs) {
1119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                break;
1120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            timeRemainedMs -= sleepIntervalMs;
1122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(sleepIntervalMs);
1123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 did not finish seeking in time for mode " + seekMode,
1125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                timeRemainedMs > 0);
1126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return cp;
1127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
1131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetTimestamp() throws Exception {
1132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int toleranceUs = 100000;
1133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final float playbackRate = 1.0f;
1134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(
1135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
1136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
1137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final Monitor onPauseCalled = new Monitor();
1140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PAUSE) {
1151fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    onPauseCalled.signal();
1152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
1156fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
1157fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1164fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1165fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1166fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
1167fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);  // let player get into stable state.
1168fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long nt1 = System.nanoTime();
1169fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaTimestamp ts1 = mPlayer.getTimestamp();
1170fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long nt2 = System.nanoTime();
1171fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("Media player should return a valid time stamp", ts1 != null);
1172fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals("MediaPlayer2 had error in clockRate " + ts1.getMediaClockRate(),
1173fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                playbackRate, ts1.getMediaClockRate(), 0.001f);
1174fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("The nanoTime of Media timestamp should be taken when getTimestamp is called.",
1175fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                nt1 <= ts1.getAnchorSytemNanoTime() && ts1.getAnchorSytemNanoTime() <= nt2);
1176fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1177fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onPauseCalled.reset();
1178fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.pause();
1179fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        onPauseCalled.waitForSignal();
1180fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ts1 = mPlayer.getTimestamp();
1181fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("Media player should return a valid time stamp", ts1 != null);
1182fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("Media player should have play rate of 0.0f when paused",
1183fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ts1.getMediaClockRate() == 0.0f);
1184fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1185fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(0, MediaPlayer2.SEEK_PREVIOUS_SYNC);
1186fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1187fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);  // let player get into stable state.
1188fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int playTime = 4000;  // The testing clip is about 10 second long.
1189fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        ts1 = mPlayer.getTimestamp();
1190fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("Media player should return a valid time stamp", ts1 != null);
1191fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(playTime);
1192fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaTimestamp ts2 = mPlayer.getTimestamp();
1193fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("Media player should return a valid time stamp", ts2 != null);
1194fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("The clockRate should not be changed.",
1195fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ts1.getMediaClockRate() == ts2.getMediaClockRate());
1196fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals("MediaPlayer2 had error in timestamp.",
1197fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ts1.getAnchorMediaTimeUs() + (long) (playTime * ts1.getMediaClockRate() * 1000),
1198fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                ts2.getAnchorMediaTimeUs(), toleranceUs);
1199fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1200fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1201fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1202fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1203fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MKV_H265_1280x720_500kbps_25fps_AAC_Stereo_128kbps_44100Hz()
1204fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1205fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1206fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz, 1280, 720);
1207fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1208fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_500kbps_25fps_AAC_Stereo_128kbps_44110Hz()
1210fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1211fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1212fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz, 480, 360);
1213fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1214fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1215fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_500kbps_30fps_AAC_Stereo_128kbps_44110Hz()
1216fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1217fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1218fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz, 480, 360);
1219fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1221fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1000kbps_25fps_AAC_Stereo_128kbps_44110Hz()
1222fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1223fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1224fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz, 480, 360);
1225fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1226fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1227fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1000kbps_30fps_AAC_Stereo_128kbps_44110Hz()
1228fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1229fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1230fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz, 480, 360);
1231fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1232fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1233fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1350kbps_25fps_AAC_Stereo_128kbps_44110Hz()
1234fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1235fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1236fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1350kbps_25fps_aac_stereo_128kbps_44100hz, 480, 360);
1237fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1239fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_128kbps_44110Hz()
1240fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1241fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1242fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz, 480, 360);
1243fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1244fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1245fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_128kbps_44110Hz_frag()
1246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1247fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz_fragmented,
1249fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                480, 360);
1250fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1251fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1252fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_192kbps_44110Hz()
1253fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1254fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz, 480, 360);
1256fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1257fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1258fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Mono_24kbps_11025Hz()
1259fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1260fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1261fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_mono_24kbps_11025hz, 176, 144);
1262fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1263fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1264fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Mono_24kbps_22050Hz()
1265fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1266fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1267fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_mono_24kbps_22050hz, 176, 144);
1268fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1269fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1270fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_24kbps_11025Hz()
1271fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1272fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1273fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_stereo_24kbps_11025hz, 176, 144);
1274fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1275fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1276fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_24kbps_22050Hz()
1277fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1278fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1279fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_stereo_24kbps_11025hz, 176, 144);
1280fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1281fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1282fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_128kbps_11025Hz()
1283fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1284fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1285fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_11025hz, 176, 144);
1286fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1288fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_128kbps_22050Hz()
1289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1290fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_11025hz, 176, 144);
1292fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1293fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1294fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Mono_24kbps_11025Hz()
1295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_11025hz, 176, 144);
1298fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Mono_24kbps_22050Hz()
1301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1302fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1303fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_22050hz, 176, 144);
1304fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1305fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1306fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_24kbps_11025Hz()
1307fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1308fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1309fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_stereo_24kbps_11025hz, 176, 144);
1310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1311fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1312fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_24kbps_22050Hz()
1313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1314fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1315fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_stereo_24kbps_11025hz, 176, 144);
1316fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1317fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1318fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_128kbps_11025Hz()
1319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1320fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1321fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_stereo_128kbps_11025hz, 176, 144);
1322fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1323fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1324fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_128kbps_22050Hz()
1325fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1326fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1327fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_56kbps_25fps_aac_stereo_128kbps_11025hz, 176, 144);
1328fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1329fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1330fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Mono_24kbps_11025Hz()
1331fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1332fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1333fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz, 176, 144);
1334fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1335fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1336fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Mono_24kbps_22050Hz()
1337fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1338fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1339fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_22050hz, 176, 144);
1340fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1341fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1342fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_24kbps_11025Hz()
1343fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1344fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1345fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_24kbps_11025hz, 176, 144);
1346fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1347fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1348fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_24kbps_22050Hz()
1349fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1350fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1351fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_24kbps_11025hz, 176, 144);
1352fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1353fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1354fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_128kbps_11025Hz()
1355fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1356fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1357fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_11025hz, 176, 144);
1358fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1359fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1360fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_128kbps_22050Hz()
1361fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1362fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1363fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_11025hz, 176, 144);
1364fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1365fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1366fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Mono_24kbps_11025Hz()
1367fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1368fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1369fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_mono_24kbps_11025hz, 176, 144);
1370fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1371fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1372fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Mono_24kbps_22050Hz()
1373fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1374fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1375fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_mono_24kbps_22050hz, 176, 144);
1376fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1377fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1378fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_24kbps_11025Hz()
1379fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1380fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1381fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_24kbps_11025hz, 176, 144);
1382fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1383fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1384fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_24kbps_22050Hz()
1385fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1386fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1387fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_24kbps_11025hz, 176, 144);
1388fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1389fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1390fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_128kbps_11025Hz()
1391fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1392fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1393fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_11025hz, 176, 144);
1394fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1395fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1396fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testLocalVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_128kbps_22050Hz()
1397fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            throws Exception {
1398fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playVideoTest(
1399fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_22050hz, 176, 144);
1400fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1401fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1402fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void readSubtitleTracks() throws Exception {
1403fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSubtitleTrackIndex.clear();
1404fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        List<MediaPlayer2.TrackInfo> trackInfos = mPlayer.getTrackInfo();
1405fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (trackInfos == null || trackInfos.size() == 0) {
1406fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
1407fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1408fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1409fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Vector<Integer> subtitleTrackIndex = new Vector<>();
1410fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < trackInfos.size(); ++i) {
1411fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(trackInfos.get(i) != null);
1412fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            if (trackInfos.get(i).getTrackType()
1413fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
1414fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                subtitleTrackIndex.add(i);
1415fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1416fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1417fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1418fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSubtitleTrackIndex.addAll(subtitleTrackIndex);
1419fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1420fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1421fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void selectSubtitleTrack(int index) throws Exception {
1422fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int trackIndex = mSubtitleTrackIndex.get(index);
1423fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.selectTrack(trackIndex);
1424fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mSelectedSubtitleIndex = index;
1425fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1426fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1427fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void deselectSubtitleTrack(int index) throws Exception {
1428fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int trackIndex = mSubtitleTrackIndex.get(index);
1429fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnDeselectTrackCalled.reset();
1430fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.deselectTrack(trackIndex);
1431fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnDeselectTrackCalled.waitForSignal();
1432fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (mSelectedSubtitleIndex == index) {
1433fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mSelectedSubtitleIndex = -1;
1434fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1435fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1436fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
14377e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @Test
14387e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @LargeTest
1439fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testDeselectTrackForSubtitleTracks() throws Throwable {
1440fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
1441fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip;
1442fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1443fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
144454e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang        mInstrumentation.waitForIdleSync();
1445fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1446fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1447fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1448fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1449fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1450fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1451fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
1452fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnInfoCalled.signal();
1453fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1454fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1455fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1456fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1457fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1458fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
1459fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnSeekCompleteCalled.signal();
1460fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
1461fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
1462fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_DESELECT_TRACK) {
1463fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mCallStatus = status;
1464fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnDeselectTrackCalled.signal();
1465fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1466fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1467fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1468fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
14697e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            public void onSubtitleData(
14707e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                    MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
1471fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (data != null && data.getData() != null) {
1472fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnSubtitleDataCalled.signal();
1473fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1474fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
14757e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        };
14767e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        synchronized (mEventCbLock) {
14777e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            mEventCallbacks.add(ecb);
14787e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        }
1479fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1480fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1481fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1482fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1483fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1484fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1485fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1486fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
1487fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1488fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
14894c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1490fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1491fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Closed caption tracks are in-band.
1492fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // So, those tracks will be found after processing a number of frames.
1493fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1494fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1495fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.reset();
1496fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1497fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1498fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        readSubtitleTracks();
1499fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1500fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Run twice to check if repeated selection-deselection on the same track works well.
1501fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        for (int i = 0; i < 2; i++) {
1502fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Waits until at least one subtitle is fired. Timeout is 2.5 seconds.
1503fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            selectSubtitleTrack(i);
1504fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mOnSubtitleDataCalled.reset();
1505fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertTrue(mOnSubtitleDataCalled.waitForSignal(2500));
1506fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1507fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            // Try deselecting track.
1508fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            deselectSubtitleTrack(i);
1509fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mOnSubtitleDataCalled.reset();
1510fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            assertFalse(mOnSubtitleDataCalled.waitForSignal(1500));
1511fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1512fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1513fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Deselecting unselected track: expected error status
1514fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
1515fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        deselectSubtitleTrack(0);
1516fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mCallStatus != MediaPlayer2.CALL_STATUS_NO_ERROR);
1517fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1518fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1519fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1520fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
15217e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @Test
15227e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @LargeTest
1523fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testChangeSubtitleTrack() throws Throwable {
1524fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
1525fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip;
1526fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1527fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1528fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1529fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1530fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1531fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1532fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1533fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
1534fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnInfoCalled.signal();
1535fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1536fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1537fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1538fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1539fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1540fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
1541fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
1542fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1543fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
15447e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
15457e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            @Override
15467e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            public void onSubtitleData(
15477e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                    MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
15487e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                if (data != null && data.getData() != null) {
15497e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                    mOnSubtitleDataCalled.signal();
15507e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                }
15517e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            }
1552fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1553fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
1554fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
1555fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1556fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1557fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1558fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1559fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1560fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1561fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1562fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1563fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
1564fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1565fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
15664c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1567fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1568fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Closed caption tracks are in-band.
1569fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // So, those tracks will be found after processing a number of frames.
1570fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1571fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1572fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.reset();
1573fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1574fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1575fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        readSubtitleTracks();
1576fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1577fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Waits until at least two captions are fired. Timeout is 2.5 sec.
1578fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        selectSubtitleTrack(0);
1579fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mOnSubtitleDataCalled.waitForCountedSignals(2, 2500) >= 2);
1580fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1581fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSubtitleDataCalled.reset();
1582fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        selectSubtitleTrack(1);
1583fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mOnSubtitleDataCalled.waitForCountedSignals(2, 2500) >= 2);
1584fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1585fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1586fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1587fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1588fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1589fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
1590fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testGetTrackInfoForVideoWithSubtitleTracks() throws Throwable {
1591fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
1592fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip;
1593fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1594fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1595fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1596fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1597fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1598fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1599fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1600fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
1601fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnInfoCalled.signal();
1602fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1603fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1604fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1605fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1606fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1607fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
1608fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
1609fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1610fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1611fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1612fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
1613fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
1614fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1615fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1616fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1617fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1618fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1619fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1620fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1621fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1622fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
1623fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1624fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
16254c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1626fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1627fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // The media metadata will be changed while playing since closed caption tracks are in-band
1628fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // and those tracks will be found after processing a number of frames. These tracks will be
1629fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // found within one second.
1630fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1631fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1632fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.reset();
1633fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnInfoCalled.waitForSignal(1500);
1634fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1635fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        readSubtitleTracks();
1636fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals(2, mSubtitleTrackIndex.size());
1637fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1638fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1639fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1640fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
16417e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @Test
16427e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    @LargeTest
16437e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    public void testMediaTimeDiscontinuity() throws Exception {
16447e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        if (!checkLoadResource(
16457e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                R.raw.bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz)) {
16467e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            return; // skip
16477e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        }
16487e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16497e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        final BlockingDeque<MediaTimestamp> timestamps = new LinkedBlockingDeque<>();
16507e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
16517e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            @Override
16527e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
16537e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
16547e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                    mOnSeekCompleteCalled.signal();
16557e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                }
16567e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            }
16577e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            @Override
16587e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            public void onMediaTimeDiscontinuity(
16597e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                    MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) {
16607e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                timestamps.add(timestamp);
16617e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang                mOnMediaTimeDiscontinuityCalled.signal();
16627e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            }
16637e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        };
16647e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        synchronized (mEventCbLock) {
16657e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            mEventCallbacks.add(ecb);
16667e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        }
16677e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16687e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
16697e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.prepare();
16707e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16717e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        // Timestamp needs to be reported when playback starts.
16727e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.reset();
16737e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.play();
16747e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        do {
16757e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
16767e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
16777e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16787e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        // Timestamp needs to be reported when seeking is done.
16797e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnSeekCompleteCalled.reset();
16807e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.reset();
16817e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.seekTo(3000);
16827e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnSeekCompleteCalled.waitForSignal();
16837e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        do {
16847e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
16857e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 1.0f) > 0.01f);
16867e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16877e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        // Timestamp needs to be updated when playback rate changes.
16887e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.reset();
16897e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.setPlaybackParams(new PlaybackParams().setSpeed(0.5f));
16907e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.waitForSignal();
16917e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        do {
16927e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
16937e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 0.5f) > 0.01f);
16947e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
16957e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        // Timestamp needs to be updated when player is paused.
16967e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.reset();
16977e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.pause();
16987e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mOnMediaTimeDiscontinuityCalled.waitForSignal();
16997e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        do {
17007e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang            assertTrue(mOnMediaTimeDiscontinuityCalled.waitForSignal(1000));
17017e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        } while (Math.abs(timestamps.getLast().getMediaClockRate() - 0.0f) > 0.01f);
17027e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
17037e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang        mPlayer.reset();
17047e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang    }
17057e23d54808f79ce964686e7551765da17bc3f585Dongwon Kang
1706fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    /*
1707fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     *  This test assumes the resources being tested are between 8 and 14 seconds long
1708fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     *  The ones being used here are 10 seconds long.
1709fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang     */
171054e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @Test
171154e40837f5a5977ff13f1c475ee7d3cb816c057fDongwon Kang    @LargeTest
1712fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testResumeAtEnd() throws Throwable {
1713fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int testsRun = testResumeAtEnd(R.raw.loudsoftmp3)
1714fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testResumeAtEnd(R.raw.loudsoftwav)
1715fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testResumeAtEnd(R.raw.loudsoftogg)
1716fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testResumeAtEnd(R.raw.loudsoftitunes)
1717fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testResumeAtEnd(R.raw.loudsoftfaac)
1718fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testResumeAtEnd(R.raw.loudsoftaac);
1719fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1720fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1721fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // returns 1 if test was run, 0 otherwise
1722fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private int testResumeAtEnd(int res) throws Throwable {
1723fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!loadResource(res)) {
1724fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Log.i(LOG_TAG, "testResumeAtEnd: No decoder found for "
1725fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    + mContext.getResources().getResourceEntryName(res) + " --- skipping.");
1726fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return 0; // skip
1727fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1728fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.reset();
1729fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1730fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1731fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1732fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1733fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1734fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
1735fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnCompletionCalled.signal();
1736fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mPlayer.play();
1737fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1738fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1739fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1740fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
1741fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1742fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1743fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1744fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1745fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1746fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // skip the first part of the file so we reach EOF sooner
1747fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(5000, MediaPlayer2.SEEK_PREVIOUS_SYNC);
1748fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1749fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // sleep long enough that we restart playback at least once, but no more
1750fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(10000);
1751fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("MediaPlayer2 should still be playing",
17524c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1753fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1754fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertEquals("wrong number of repetitions", 1, mOnCompletionCalled.getNumSignal());
1755fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return 1;
1756fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1757fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1758fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1759fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
1760fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPositionAtEnd() throws Throwable {
1761fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        int testsRun = testPositionAtEnd(R.raw.test1m1shighstereo)
1762fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftmp3)
1763fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftwav)
1764fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftogg)
1765fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftitunes)
1766fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftfaac)
1767fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                + testPositionAtEnd(R.raw.loudsoftaac);
1768fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1769fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1770fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private int testPositionAtEnd(int res) throws Throwable {
1771fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!loadResource(res)) {
1772fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Log.i(LOG_TAG, "testPositionAtEnd: No decoder found for "
1773fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    + mContext.getResources().getResourceEntryName(res) + " --- skipping.");
1774fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return 0; // skip
1775fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1776fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        AudioAttributesCompat attributes = new AudioAttributesCompat.Builder()
1777fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setLegacyStreamType(AudioManager.STREAM_MUSIC)
1778fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build();
1779fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setAudioAttributes(attributes);
1780fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1781fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.reset();
1782fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1783fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1784fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1785fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1786fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1787fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
1788fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnCompletionCalled.signal();
1789fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1790fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1791fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1792fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1793fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1794fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
1795fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
1796fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1797fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1798fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1799fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
1800fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1801fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
1802fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1803fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1804fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1805fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        long duration = mPlayer.getDuration();
1806fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue("resource too short", duration > 6000);
1807fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(duration - 5000, MediaPlayer2.SEEK_PREVIOUS_SYNC);
1808fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
1809fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1810fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
18114c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
1812fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Log.i("@@@@", "position: " + mPlayer.getCurrentPosition());
1813fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(500);
1814fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1815fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Log.i("@@@@", "final position: " + mPlayer.getCurrentPosition());
1816fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mPlayer.getCurrentPosition() > duration - 1000);
1817fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1818fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return 1;
1819fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1820fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1821fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
1822fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
18231666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    public void testMediaPlayer2Callback() throws Throwable {
1824fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int mp4Duration = 8484;
1825fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1826fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!checkLoadResource(R.raw.testvideo)) {
1827fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip;
1828fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1829fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1830fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
1831fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1832fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.reset();
1833fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
1834fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1835fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd,
1836fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    int width, int height) {
1837fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mOnVideoSizeChangedCalled.signal();
1838fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1839fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1840fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1841fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1842fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mOnErrorCalled.signal();
1843fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1844fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1845fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1846fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
1847fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mOnInfoCalled.signal();
1848fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1849fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
1850fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
1851fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
1852fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnCompletionCalled.signal();
1853fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1854fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1855fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1856fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
1857fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
1858fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
1859fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnSeekCompleteCalled.signal();
1860fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
1861fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
1862fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
1863fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
1864fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
1865fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
1866fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
1867fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
1868fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1869fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mOnPrepareCalled.isSignalled());
1870fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mOnVideoSizeChangedCalled.isSignalled());
1871fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
1872fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
1873fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnVideoSizeChangedCalled.waitForSignal();
1874fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1875fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.reset();
1876fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(mp4Duration >> 1, MediaPlayer2.SEEK_PREVIOUS_SYNC);
1877fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnSeekCompleteCalled.waitForSignal();
1878fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
1879fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mOnCompletionCalled.isSignalled());
1880fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
1881fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
18824c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
1883fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
1884fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
18854c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertFalse(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
1886fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnCompletionCalled.waitForSignal();
1887fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertFalse(mOnErrorCalled.isSignalled());
1888fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
1889fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
1890fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
18911666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    @Test
18921666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    @LargeTest
18931666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    public void testPlayerStates() throws Throwable {
18941666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final int mp4Duration = 8484;
18951666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
18961666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        if (!checkLoadResource(R.raw.testvideo)) {
18971666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            return; // skip;
18981666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        }
18991666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
19001666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19011666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor prepareCompleted = new Monitor();
19021666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor playCompleted = new Monitor();
19031666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor pauseCompleted = new Monitor();
19041666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19051666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
19061666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
19071666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
19081666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                if (what == MediaPlayer2.CALL_COMPLETED_PREPARE) {
19091666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                    prepareCompleted.signal();
19101666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
19111666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                    playCompleted.signal();
19121666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                } else if (what == MediaPlayer2.CALL_COMPLETED_PAUSE) {
19131666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                    pauseCompleted.signal();
19141666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                }
19151666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
19161666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        };
19171666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        synchronized (mEventCbLock) {
19181666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            mEventCallbacks.add(ecb);
19191666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        }
19201666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19214c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        MediaPlayerInterface playerBase = mPlayer.getMediaPlayerInterface();
19224c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.BUFFERING_STATE_UNKNOWN, playerBase.getBufferingState());
19234c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.PLAYER_STATE_IDLE, playerBase.getPlayerState());
19241666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        prepareCompleted.reset();
19254c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        playerBase.prepare();
19261666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        prepareCompleted.waitForSignal();
19274c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
19284c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                playerBase.getBufferingState());
19294c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.PLAYER_STATE_PAUSED, playerBase.getPlayerState());
19304c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayer2.MEDIAPLAYER2_STATE_PREPARED, mPlayer.getMediaPlayer2State());
19311666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19321666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        playCompleted.reset();
19334c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        playerBase.play();
19341666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        playCompleted.waitForSignal();
19354c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
19364c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                playerBase.getBufferingState());
19374c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.PLAYER_STATE_PLAYING, playerBase.getPlayerState());
19381666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19391666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        pauseCompleted.reset();
19404c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        playerBase.pause();
19411666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        pauseCompleted.waitForSignal();
19424c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
19434c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                playerBase.getBufferingState());
19444c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.PLAYER_STATE_PAUSED, playerBase.getPlayerState());
19451666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19464c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        playerBase.reset();
19474c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.BUFFERING_STATE_UNKNOWN, playerBase.getBufferingState());
19484c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertEquals(MediaPlayerInterface.PLAYER_STATE_IDLE, playerBase.getPlayerState());
19491666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    }
19501666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19511666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    @Test
19521666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    @LargeTest
19531666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    public void testPlayerEventCallback() throws Throwable {
19541666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final int mp4Duration = 8484;
19551666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19561666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        if (!checkLoadResource(R.raw.testvideo)) {
19571666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            return; // skip;
19581666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        }
195948178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang        final DataSourceDesc dsd2 = createDataSourceDesc(
196048178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz);
196148178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang        mPlayer.setNextDataSource(dsd2);
19621666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19631666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        mPlayer.setSurface(mActivity.getSurfaceHolder().getSurface());
19641666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
196548178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang        final Monitor onDsdChangedCalled = new Monitor();
19661666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor onPrepareCalled = new Monitor();
19671666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor onSeekCompleteCalled = new Monitor();
19681666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor onPlayerStateChangedCalled = new Monitor();
19691666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final AtomicInteger playerState = new AtomicInteger();
19701666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor onBufferingStateChangedCalled = new Monitor();
19711666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final AtomicInteger bufferingState = new AtomicInteger();
19721666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final Monitor onPlaybackSpeedChanged = new Monitor();
19731666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        final AtomicReference<Float> playbackSpeed = new AtomicReference<>();
19741666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19754c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        PlayerEventCallback callback = new PlayerEventCallback() {
197648178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang            @Override
19774c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onCurrentDataSourceChanged(MediaPlayerInterface mpb, DataSourceDesc dsd) {
197848178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang                onDsdChangedCalled.signal();
197948178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang            }
198048178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang
19811666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
19824c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onMediaPrepared(MediaPlayerInterface mpb, DataSourceDesc dsd) {
19831666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                onPrepareCalled.signal();
19841666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
19851666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19861666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
19874c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onPlayerStateChanged(MediaPlayerInterface mpb, int state) {
19881666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                playerState.set(state);
19891666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                onPlayerStateChangedCalled.signal();
19901666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
19911666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19921666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
19934c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onBufferingStateChanged(MediaPlayerInterface mpb, DataSourceDesc dsd,
19941666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                    int state) {
19951666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                bufferingState.set(state);
19961666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                onBufferingStateChangedCalled.signal();
19971666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
19981666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
19991666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
20004c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onPlaybackSpeedChanged(MediaPlayerInterface mpb, float speed) {
20011666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                playbackSpeed.set(speed);
20021666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                onPlaybackSpeedChanged.signal();
20031666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
20041666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20051666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            @Override
20064c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang            public void onSeekCompleted(MediaPlayerInterface mpb, long position) {
20071666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang                onSeekCompleteCalled.signal();
20081666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            }
20091666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        };
20104c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        MediaPlayerInterface basePlayer = mPlayer.getMediaPlayerInterface();
20111666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        ExecutorService executor = Executors.newFixedThreadPool(1);
20124c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.registerPlayerEventCallback(executor, callback);
20131666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20141666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onPrepareCalled.reset();
20151666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onPlayerStateChangedCalled.reset();
20161666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onBufferingStateChangedCalled.reset();
20174c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.prepare();
20181666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        do {
20191666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            assertTrue(onBufferingStateChangedCalled.waitForSignal(1000));
20204c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        } while (bufferingState.get()
20214c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                != MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_STARVED);
20221666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20231666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        assertTrue(onPrepareCalled.waitForSignal(1000));
20241666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        do {
20251666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            assertTrue(onPlayerStateChangedCalled.waitForSignal(1000));
20264c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        } while (playerState.get() != MediaPlayerInterface.PLAYER_STATE_PAUSED);
20271666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        do {
20281666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            assertTrue(onBufferingStateChangedCalled.waitForSignal(1000));
20294c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        } while (bufferingState.get()
20304c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang                != MediaPlayerInterface.BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
20311666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20321666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onSeekCompleteCalled.reset();
20334c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.seekTo(mp4Duration >> 1);
20341666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onSeekCompleteCalled.waitForSignal();
20351666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20361666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        onPlaybackSpeedChanged.reset();
20374c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.setPlaybackSpeed(0.5f);
20381666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        do {
20391666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang            assertTrue(onPlaybackSpeedChanged.waitForSignal(1000));
20401666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        } while (Math.abs(playbackSpeed.get() - 0.5f) > FLOAT_TOLERANCE);
20411666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20424c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.skipToNext();
204348178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang        assertTrue(onDsdChangedCalled.waitForSignal(1000));
204448178a342105131d87b55c92dd96d51da4d55dd7Dongwon Kang
20454c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.reset();
20461666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
20474c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        basePlayer.unregisterPlayerEventCallback(callback);
20481666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang        executor.shutdown();
20491666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang    }
20501666681701b52318c2b24e8b79de1304cc721ea1Dongwon Kang
2051fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testRecordAndPlay() throws Exception {
2052fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!hasMicrophone()) {
2053fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
2054fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2055fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /* FIXME: check the codec exists.
2056fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
2057fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                || !MediaUtils.checkEncoder(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
2058fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return; // skip
2059fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2060fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        */
2061fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        File outputFile = new File(Environment.getExternalStorageDirectory(),
2062fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                "record_and_play.3gp");
2063fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        String outputFileLocation = outputFile.getAbsolutePath();
2064fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
2065fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            recordMedia(outputFileLocation);
2066fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2067fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Uri uri = Uri.parse(outputFileLocation);
2068fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            MediaPlayer2 mp = MediaPlayer2.create();
2069fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            try {
2070fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.setDataSource(new DataSourceDesc.Builder()
2071fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .setDataSource(mContext, uri)
2072fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                        .build());
2073fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.prepare();
2074fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                Thread.sleep(SLEEP_TIME);
2075fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                playAndStop(mp);
2076fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            } finally {
2077fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp.close();
2078fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2079fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2080fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            try {
2081fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp = createMediaPlayer2(mContext, uri);
2082fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                playAndStop(mp);
2083fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            } finally {
2084fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (mp != null) {
2085fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mp.close();
2086fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2087fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2088fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2089fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            try {
2090fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                mp = createMediaPlayer2(mContext, uri, mActivity.getSurfaceHolder());
2091fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                playAndStop(mp);
2092fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            } finally {
2093fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (mp != null) {
2094fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mp.close();
2095fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2096fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2097fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
2098fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            outputFile.delete();
2099fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2100fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2101fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2102fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void playAndStop(MediaPlayer2 mp) throws Exception {
2103fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mp.play();
2104fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
2105fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mp.reset();
2106fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2107fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2108fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private void recordMedia(String outputFile) throws Exception {
2109fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaRecorder mr = new MediaRecorder();
2110fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        try {
2111fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.setAudioSource(MediaRecorder.AudioSource.MIC);
2112fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
2113fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
2114fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.setOutputFile(outputFile);
2115fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2116fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.prepare();
2117fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.start();
2118fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
2119fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.stop();
2120fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        } finally {
2121fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mr.release();
2122fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2123fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2124fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2125fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    private boolean hasMicrophone() {
2126fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        return mActivity.getPackageManager().hasSystemFeature(
2127fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                PackageManager.FEATURE_MICROPHONE);
2128fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2129fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2130fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    // Smoke test playback from a Media2DataSource.
2131fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
2132fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
2133fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlaybackFromAMedia2DataSource() throws Exception {
2134fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
2135fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int duration = 10000;
2136fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2137fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /* FIXME: check the codec exists.
2138fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
2139fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
2140fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2141fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        */
2142fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2143fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        TestMedia2DataSource dataSource =
2144fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                TestMedia2DataSource.fromAssetFd(mResources.openRawResourceFd(resid));
2145fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test returning -1 from getSize() to indicate unknown size.
2146fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        dataSource.returnFromGetSize(-1);
2147fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
2148fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDataSource(dataSource)
2149fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build());
2150fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        playLoadedVideo(null, null, -1);
21514c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
2152fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2153fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test pause and restart.
2154fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.pause();
2155fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        Thread.sleep(SLEEP_TIME);
21564c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertFalse(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
2157fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2158fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
2159fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2160fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
2161fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
2162fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
2163fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2164fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2165fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2166fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2167fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
2168fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_PLAY) {
2169fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
2170fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2171fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2172fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
2173fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
2174fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2175fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
2176fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
2177fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
21784c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
2179fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2180fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test reset.
2181fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
2182fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
2183fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDataSource(dataSource)
2184fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build());
2185fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2186fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
2187fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2188fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
2189fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
2190fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
2191fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2192fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.reset();
2193fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
2194fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
21954c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        assertTrue(mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING);
2196fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2197fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // Test seek. Note: the seek position is cached and returned as the
2198fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        // current position so there's no point in comparing them.
2199fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.seekTo(duration - SLEEP_TIME, MediaPlayer2.SEEK_PREVIOUS_SYNC);
22004c2e24f0a0e63fa260e959395d27b6e0ec95555aDongwon Kang        while (mPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING) {
2201fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            Thread.sleep(SLEEP_TIME);
2202fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2203fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2204fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2205fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
2206fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
2207fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testNullMedia2DataSourceIsRejected() throws Exception {
2208fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
2209fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2210fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
2211fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
2212fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mCallStatus = status;
2213fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
2214fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2215fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2216fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
2217fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
2218fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2219fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
2220fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource((DataSourceDesc) null);
2221fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
2222fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mCallStatus != MediaPlayer2.CALL_STATUS_NO_ERROR);
2223fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2224fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2225fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
2226fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
2227fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testMedia2DataSourceIsClosedOnReset() throws Exception {
2228fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
2229fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2230fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
2231fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
2232fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mCallStatus = status;
2233fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPlayCalled.signal();
2234fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2235fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2236fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
2237fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setMediaPlayer2EventCallback(mExecutor, ecb);
2238fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2239fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        TestMedia2DataSource dataSource = new TestMedia2DataSource(new byte[0]);
2240fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
2241fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDataSource(dataSource)
2242fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build());
2243fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPlayCalled.waitForSignal();
2244fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.reset();
2245fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(dataSource.isClosed());
2246fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2247fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2248fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
2249fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
2250fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlaybackFailsIfMedia2DataSourceThrows() throws Exception {
2251fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
2252fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /* FIXME: check the codec exists.
2253fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
2254fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
2255fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2256fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        */
2257fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2258fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        setOnErrorListener();
2259fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        TestMedia2DataSource dataSource =
2260fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                TestMedia2DataSource.fromAssetFd(mResources.openRawResourceFd(resid));
2261fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
2262fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDataSource(dataSource)
2263fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build());
2264fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2265fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
2266fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2267fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
2268fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
2269fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
2270fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2271fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2272fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
2273fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
2274fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
2275fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2276fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2277fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
2278fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
2279fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
2280fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2281fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        dataSource.throwFromReadAt();
2282fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
2283fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mOnErrorCalled.waitForSignal());
2284fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
2285fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2286fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @Test
2287fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    @LargeTest
2288fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    public void testPlaybackFailsIfMedia2DataSourceReturnsAnError() throws Exception {
2289fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
2290fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        /* FIXME: check the codec exists.
2291fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
2292fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            return;
2293fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2294fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        */
2295fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2296fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        TestMedia2DataSource dataSource =
2297fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                TestMedia2DataSource.fromAssetFd(mResources.openRawResourceFd(resid));
2298fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
2299fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .setDataSource(dataSource)
2300fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                .build());
2301fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2302fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        setOnErrorListener();
2303fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
2304fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            @Override
2305fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
2306fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
2307fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                    mOnPrepareCalled.signal();
2308fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang                }
2309fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            }
2310fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        };
2311fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        synchronized (mEventCbLock) {
2312fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang            mEventCallbacks.add(ecb);
2313fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        }
2314fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2315fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.reset();
2316fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.prepare();
2317fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mOnPrepareCalled.waitForSignal();
2318fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang
2319fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        dataSource.returnFromReadAt(-2);
2320fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        mPlayer.play();
2321fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang        assertTrue(mOnErrorCalled.waitForSignal());
2322fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang    }
232398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
232498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang    @Test
232598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang    @SmallTest
232698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang    public void testClearPendingCommands() throws Exception {
232798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        final Monitor readAllowed = new Monitor();
232898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        Media2DataSource dataSource = new Media2DataSource() {
232998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
233098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public int readAt(long position, byte[] buffer, int offset, int size)
233198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                    throws IOException {
233298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                try {
233398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                    readAllowed.waitForSignal();
233498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                } catch (InterruptedException e) {
233598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                    fail();
233698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                }
233798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                return -1;
233898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            }
233998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
234098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
234198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public long getSize() throws IOException {
234298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                return -1;  // Unknown size
234398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            }
234498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
234598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
234698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public void close() throws IOException {}
234798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        };
234898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        final ArrayDeque<Integer> commandsCompleted = new ArrayDeque<>();
234998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        setOnErrorListener();
235098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        MediaPlayer2.MediaPlayer2EventCallback ecb = new MediaPlayer2.MediaPlayer2EventCallback() {
235198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
235298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
235398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
235498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                    mOnPrepareCalled.signal();
235598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                }
235698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            }
235798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
235898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
235998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
236098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                commandsCompleted.add(what);
236198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            }
236298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
236398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            @Override
236498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
236598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                mOnErrorCalled.signal();
236698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            }
236798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        };
236898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        synchronized (mEventCbLock) {
236998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang            mEventCallbacks.add(ecb);
237098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        }
237198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
237298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mOnPrepareCalled.reset();
237398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mOnErrorCalled.reset();
237498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
237598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.setDataSource(new DataSourceDesc.Builder()
237698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                .setDataSource(dataSource)
237798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                .build());
237898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
237998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        // prepare() will be pending until readAllowed is signaled.
238098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.prepare();
238198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
238298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.play();
238398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.pause();
238498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.play();
238598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.pause();
238698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.play();
238798d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mPlayer.seekTo(1000);
238898d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang
238998d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        // Cause a failure on the pending prepare operation.
239098d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        readAllowed.signal();
239198d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        mOnErrorCalled.waitForSignal();
239298d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        assertEquals(0, mOnPrepareCalled.getNumSignal());
239398d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        assertEquals(1, commandsCompleted.size());
239498d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang        assertEquals(MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE,
239598d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang                (int) commandsCompleted.peekFirst());
239698d2ac4586aa768080d5278f2e5e9dd4cce40fbeDongwon Kang    }
2397fbbf807584a0fbe7a01a0aa9920330cad45689aaInsun Kang}
2398