1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.mediaframeworktest.functional;
18
19
20
21//import android.content.Resources;
22import com.android.mediaframeworktest.MediaFrameworkTest;
23import com.android.mediaframeworktest.MediaNames;
24
25import android.content.res.AssetFileDescriptor;
26import android.graphics.Bitmap;
27import android.graphics.BitmapFactory;
28import android.media.MediaMetadataRetriever;
29import android.media.MediaPlayer;
30import android.media.MediaRecorder;
31import android.os.Looper;
32import android.os.SystemClock;
33import android.util.Log;
34
35import java.io.File;
36import java.io.FileWriter;
37import java.io.IOException;
38import java.io.InputStream;
39import java.io.OutputStream;
40import java.io.Writer;
41import java.io.FileOutputStream;
42import java.util.Random;
43/**
44 * Junit / Instrumentation test case for the media player api
45
46 */
47public class CodecTest {
48    private static String TAG = "CodecTest";
49    private static MediaPlayer mMediaPlayer;
50    private MediaPlayer.OnPreparedListener mOnPreparedListener;
51
52    private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000;  //1 min max.
53    private static boolean mInitialized = false;
54    private static boolean mPrepareReset = false;
55    private static Looper mLooper = null;
56    private static final Object lock = new Object();
57    private static final Object prepareDone = new Object();
58    private static final Object videoSizeChanged = new Object();
59    private static final Object onCompletion = new Object();
60    private static boolean onPrepareSuccess = false;
61    public static boolean onCompleteSuccess = false;
62    public static boolean mPlaybackError = false;
63    public static boolean mFailedToCompleteWithNoError = true;
64    public static int mMediaInfoUnknownCount = 0;
65    public static int mMediaInfoVideoTrackLaggingCount = 0;
66    public static int mMediaInfoBadInterleavingCount = 0;
67    public static int mMediaInfoNotSeekableCount = 0;
68    public static int mMediaInfoMetdataUpdateCount = 0;
69
70    public static String printCpuInfo(){
71        String cm = "dumpsys cpuinfo";
72        String cpuinfo =null;
73        int ch;
74        try{
75            Process  p = Runtime.getRuntime().exec(cm);
76            InputStream in = p.getInputStream();
77            StringBuffer sb = new StringBuffer(512);
78            while ( ( ch = in.read() ) != -1 ){
79                sb.append((char) ch);
80            }
81            cpuinfo = sb.toString();
82        }catch (IOException e){
83            Log.v(TAG, e.toString());
84        }
85        return cpuinfo;
86    }
87
88
89    public static int getDuration(String filePath) {
90        Log.v(TAG, "getDuration - " + filePath);
91        MediaPlayer mp = new MediaPlayer();
92        try{
93            mp.setDataSource(filePath);
94            mp.prepare();
95        }catch (Exception e){
96            Log.v(TAG, e.toString());
97        }
98        int duration = mp.getDuration();
99        Log.v(TAG, "Duration " + duration);
100        mp.release();
101        Log.v(TAG, "release");
102        return duration;
103    }
104
105    public static boolean getCurrentPosition(String filePath){
106        Log.v(TAG, "GetCurrentPosition - " + filePath);
107        int currentPosition = 0;
108        long t1=0;
109        long t2 =0;
110        MediaPlayer mp = new MediaPlayer();
111        try{
112            mp.setDataSource(filePath);
113            Log.v(TAG, "start playback");
114            mp.prepare();
115            mp.start();
116            t1=SystemClock.uptimeMillis();
117            Thread.sleep(10000);
118            mp.pause();
119            Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
120            t2=SystemClock.uptimeMillis();
121        }catch (Exception e){
122            Log.v(TAG, e.toString());
123        }
124        currentPosition = mp.getCurrentPosition();
125        mp.stop();
126        mp.release();
127        Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
128        //The currentposition should be within 10% of the sleep time
129        //For the very short mp3, it should return the length instead of 10 seconds
130        if (filePath.equals(MediaNames.SHORTMP3)){
131            if (currentPosition < 1000 )
132                return true;
133        }
134        if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
135            return true;
136        else
137            return false;
138    }
139
140    public static boolean seekTo(String filePath){
141        Log.v(TAG, "seekTo " + filePath);
142        int currentPosition = 0;
143        MediaPlayer mp = new MediaPlayer();
144        try{
145            mp.setDataSource(filePath);
146            mp.prepare();
147            mp.start();
148            mp.seekTo(MediaNames.SEEK_TIME);
149            Thread.sleep(MediaNames.WAIT_TIME);
150            currentPosition = mp.getCurrentPosition();
151        }catch (Exception e){
152            Log.v(TAG, e.getMessage());
153        }
154        mp.stop();
155        mp.release();
156        Log.v(TAG, "CurrentPosition = " + currentPosition);
157        //The currentposition should be at least greater than the 80% of seek time
158        if ((currentPosition > MediaNames.SEEK_TIME *0.8))
159            return true;
160        else
161            return false;
162    }
163
164    public static boolean setLooping(String filePath){
165        int currentPosition = 0;
166        int duration = 0;
167        long t1 =0;
168        long t2 =0;
169        Log.v (TAG, "SetLooping - " + filePath);
170        MediaPlayer mp = new MediaPlayer();
171        try{
172            mp.setDataSource(filePath);
173            mp.prepare();
174            duration = mp.getDuration();
175            Log.v(TAG, "setLooping duration " + duration);
176            mp.setLooping(true);
177            mp.start();
178            Thread.sleep(5000);
179            mp.seekTo(duration - 5000);
180            t1=SystemClock.uptimeMillis();
181            Thread.sleep(20000);
182            t2=SystemClock.uptimeMillis();
183            Log.v(TAG, "pause");
184            //Bug# 1106852 - IllegalStateException will be thrown if pause is called
185            //in here
186            //mp.pause();
187            currentPosition = mp.getCurrentPosition();
188            Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1));
189        }catch (Exception e){
190            Log.v(TAG, "Exception : " + e.toString());
191        }
192        mp.stop();
193        mp.release();
194        //The current position should be within 20% of the sleep time
195        //and should be greater than zero.
196        if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0)
197            return true;
198        else
199            return false;
200    }
201
202    public static boolean pause(String filePath) throws Exception {
203        Log.v(TAG, "pause - " + filePath);
204        boolean misPlaying = true;
205        boolean pauseResult = false;
206        long t1=0;
207        long t2=0;
208        MediaPlayer mp = new MediaPlayer();
209        mp.setDataSource(filePath);
210        mp.prepare();
211        int duration = mp.getDuration();
212        mp.start();
213        t1=SystemClock.uptimeMillis();
214        Thread.sleep(5000);
215        mp.pause();
216        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
217        t2=SystemClock.uptimeMillis();
218        misPlaying = mp.isPlaying();
219        int curPosition = mp.getCurrentPosition();
220        Log.v(TAG, filePath + " pause currentPositon " + curPosition);
221        Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) );
222        String cpuinfo = printCpuInfo();
223        Log.v(TAG, cpuinfo);
224        if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false))
225            pauseResult = true;
226        mp.stop();
227        mp.release();
228        return pauseResult;
229    }
230
231    public static void prepareStopRelease(String filePath) throws Exception {
232        Log.v(TAG, "prepareStopRelease" + filePath);
233        MediaPlayer mp = new MediaPlayer();
234        mp.setDataSource(filePath);
235        mp.prepare();
236        mp.stop();
237        mp.release();
238    }
239
240    public static void preparePauseRelease(String filePath) throws Exception {
241        Log.v(TAG, "preparePauseRelease" + filePath);
242        MediaPlayer mp = new MediaPlayer();
243        mp.setDataSource(filePath);
244        mp.prepare();
245        mp.pause();
246        mp.release();
247    }
248
249    static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener =
250        new MediaPlayer.OnVideoSizeChangedListener() {
251            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
252                synchronized (videoSizeChanged) {
253                    Log.v(TAG, "sizechanged notification received ...");
254                    videoSizeChanged.notify();
255                }
256            }
257    };
258
259    //Register the videoSizeChanged listener
260    public static int videoHeight(String filePath) throws Exception {
261        Log.v(TAG, "videoHeight - " + filePath);
262        int videoHeight = 0;
263        synchronized (lock) {
264            initializeMessageLooper();
265            try {
266                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
267            } catch(Exception e) {
268                Log.v(TAG, "looper was interrupted.");
269                return 0;
270            }
271        }
272        try {
273            mMediaPlayer.setDataSource(filePath);
274            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
275            mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
276            synchronized (videoSizeChanged) {
277                try {
278                    mMediaPlayer.prepare();
279                    mMediaPlayer.start();
280                    videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
281                } catch (Exception e) {
282                    Log.v(TAG, "wait was interrupted");
283                }
284            }
285            videoHeight = mMediaPlayer.getVideoHeight();
286            terminateMessageLooper();
287        } catch (Exception e) {
288            Log.e(TAG, e.getMessage());
289        }
290
291        return videoHeight;
292    }
293
294    //Register the videoSizeChanged listener
295    public static int videoWidth(String filePath) throws Exception {
296        Log.v(TAG, "videoWidth - " + filePath);
297        int videoWidth = 0;
298
299        synchronized (lock) {
300            initializeMessageLooper();
301            try {
302                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
303            } catch(Exception e) {
304                Log.v(TAG, "looper was interrupted.");
305                return 0;
306            }
307        }
308        try {
309            mMediaPlayer.setDataSource(filePath);
310            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
311            mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
312            synchronized (videoSizeChanged) {
313                try {
314                    mMediaPlayer.prepare();
315                    mMediaPlayer.start();
316                    videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
317                } catch (Exception e) {
318                    Log.v(TAG, "wait was interrupted");
319                }
320            }
321            videoWidth = mMediaPlayer.getVideoWidth();
322            terminateMessageLooper();
323        } catch (Exception e) {
324            Log.e(TAG, e.getMessage());
325        }
326        return videoWidth;
327    }
328
329    //This also test the streaming video which may take a long
330    //time to start the playback.
331    public static boolean videoSeekTo(String filePath) throws Exception {
332        Log.v(TAG, "videoSeekTo - " + filePath);
333        int currentPosition = 0;
334        int duration = 0;
335        boolean videoResult = false;
336        MediaPlayer mp = new MediaPlayer();
337        mp.setDataSource(filePath);
338        mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
339        mp.prepare();
340        mp.start();
341        if (filePath.equals(MediaNames.VIDEO_SHORT_3GP)){
342            mp.pause();
343            Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
344            mp.seekTo(0);
345            mp.start();
346            Thread.sleep(1000);
347            currentPosition = mp.getCurrentPosition();
348            Log.v(TAG,"short position " + currentPosition);
349            if (currentPosition > 100 )
350                return true;
351            else
352                return false;
353        }
354        Thread.sleep(5000);
355        duration = mp.getDuration();
356        Log.v(TAG, "video duration " + duration);
357        mp.pause();
358        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
359        mp.seekTo(duration - 20000 );
360        mp.start();
361        Thread.sleep(1000);
362        mp.pause();
363        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
364        mp.seekTo(duration/2);
365        mp.start();
366        Thread.sleep(10000);
367        currentPosition = mp.getCurrentPosition();
368        Log.v(TAG, "video currentPosition " + currentPosition);
369        mp.release();
370        if (currentPosition > (duration /2 )*0.9)
371            return true;
372        else
373            return false;
374
375    }
376
377    public static boolean seekToEnd(String filePath){
378        Log.v(TAG, "seekToEnd - " + filePath);
379        int duration = 0;
380        int currentPosition = 0;
381        boolean isPlaying = false;
382        MediaPlayer mp = new MediaPlayer();
383        try{
384            mp.setDataSource(filePath);
385            Log.v(TAG, "start playback");
386            mp.prepare();
387            duration = mp.getDuration();
388            mp.seekTo(duration - 3000);
389            mp.start();
390            Thread.sleep(6000);
391        }catch (Exception e){}
392        isPlaying = mp.isPlaying();
393        currentPosition = mp.getCurrentPosition();
394        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
395        mp.stop();
396        mp.release();
397        Log.v(TAG, "duration = " + duration);
398        if (currentPosition < 0.9 * duration || isPlaying)
399            return false;
400        else
401            return true;
402    }
403
404    public static boolean shortMediaStop(String filePath){
405        Log.v(TAG, "shortMediaStop - " + filePath);
406        //This test is only for the short media file
407        int duration = 0;
408        int currentPosition = 0;
409        boolean isPlaying = false;
410        MediaPlayer mp = new MediaPlayer();
411        try{
412            mp.setDataSource(filePath);
413            Log.v(TAG, "start playback");
414            mp.prepare();
415            duration = mp.getDuration();
416            mp.start();
417            Thread.sleep(10000);
418        }catch (Exception e){}
419        isPlaying = mp.isPlaying();
420        currentPosition = mp.getCurrentPosition();
421        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
422        mp.stop();
423        mp.release();
424        Log.v(TAG, "duration = " + duration);
425        if (currentPosition > duration || isPlaying)
426            return false;
427        else
428            return true;
429    }
430
431    public static boolean playToEnd(String filePath){
432        Log.v(TAG, "shortMediaStop - " + filePath);
433        //This test is only for the short media file
434        int duration = 200000;
435        int updateDuration = 0;
436        int currentPosition = 0;
437        boolean isPlaying = false;
438        MediaPlayer mp = new MediaPlayer();
439        try{
440            Thread.sleep(5000);
441            mp.setDataSource(filePath);
442            Log.v(TAG, "start playback");
443            mp.prepare();
444            //duration = mp.getDuration();
445            mp.start();
446            Thread.sleep(50000);
447        }catch (Exception e){}
448        isPlaying = mp.isPlaying();
449        currentPosition = mp.getCurrentPosition();
450        //updateDuration = mp.getDuration();
451        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
452        mp.stop();
453        mp.release();
454        //Log.v(TAG, "duration = " + duration);
455        //Log.v(TAG, "Update duration = " + updateDuration);
456        if (currentPosition > duration || isPlaying)
457            return false;
458        else
459            return true;
460    }
461
462    public static boolean seektoBeforeStart(String filePath){
463        Log.v(TAG, "seektoBeforeStart - " + filePath);
464        //This test is only for the short media file
465        int duration = 0;
466        int currentPosition = 0;
467
468        MediaPlayer mp = new MediaPlayer();
469        try{
470            mp.setDataSource(filePath);
471            mp.prepare();
472            duration = mp.getDuration();
473            mp.seekTo(duration - 10000);
474            mp.start();
475            currentPosition=mp.getCurrentPosition();
476            mp.stop();
477            mp.release();
478        }catch (Exception e){}
479        if (currentPosition < duration/2)
480            return false;
481        else
482            return true;
483    }
484
485    public static boolean mediaRecorderRecord(String filePath){
486        Log.v(TAG, "SoundRecording - " + filePath);
487        //This test is only for the short media file
488        int duration = 0;
489        try{
490            MediaRecorder mRecorder = new MediaRecorder();
491            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
492            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
493            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
494            mRecorder.setOutputFile(filePath);
495            mRecorder.prepare();
496            mRecorder.start();
497            Thread.sleep(500);
498            mRecorder.stop();
499            Log.v(TAG, "sound recorded");
500            mRecorder.release();
501        }catch (Exception e){
502            Log.v(TAG, e.toString());
503        }
504
505        //Verify the recorded file
506        MediaPlayer mp = new MediaPlayer();
507        try{
508            mp.setDataSource(filePath);
509            mp.prepare();
510            duration = mp.getDuration();
511            Log.v(TAG,"Duration " + duration);
512            mp.release();
513        }catch (Exception e){}
514        //Check the record media file length is greate than zero
515        if (duration > 0)
516            return true;
517        else
518            return false;
519
520    }
521
522    //Test for mediaMeta Data Thumbnail
523    public static boolean getThumbnail(String filePath, String goldenPath){
524        Log.v(TAG, "getThumbnail - " + filePath);
525
526        int goldenHeight = 0;
527        int goldenWidth = 0;
528        int outputWidth = 0;
529        int outputHeight = 0;
530
531        //This test is only for the short media file
532        try{
533            BitmapFactory mBitmapFactory = new BitmapFactory();
534
535            MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
536            try {
537                mMediaMetadataRetriever.setDataSource(filePath);
538            } catch(Exception e) {
539                e.printStackTrace();
540                return false;
541            }
542            Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1);
543
544            //Verify the thumbnail
545            Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
546            outputWidth = outThumbnail.getWidth();
547            outputHeight = outThumbnail.getHeight();
548            goldenHeight = goldenBitmap.getHeight();
549            goldenWidth = goldenBitmap.getWidth();
550
551            //check the image dimension
552            if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight))
553                return false;
554
555            // Check half line of pixel
556            int x = goldenHeight / 2;
557            for (int j = 1; j < goldenWidth / 2; j++) {
558                if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)) {
559                    Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j));
560                    return false;
561                }
562           }
563        }catch (Exception e){
564            Log.v(TAG, e.toString());
565            return false;
566        }
567        return true;
568    }
569
570    //Load midi file from resources
571    public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration){
572        int duration = 0;
573        try{
574            MediaPlayer mp = new MediaPlayer();
575            mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
576            mp.prepare();
577            mp.start();
578            duration = mp.getDuration();
579            Thread.sleep(5000);
580            mp.release();
581        }catch (Exception e){
582            Log.v(TAG,e.getMessage());
583        }
584        if (duration > expectedDuration)
585            return true;
586        else
587            return false;
588    }
589
590    public static boolean prepareAsyncReset(String filePath){
591        //preparesAsync
592        try{
593            MediaPlayer mp = new MediaPlayer();
594            mp.setDataSource(filePath);
595            mp.prepareAsync();
596            mp.reset();
597            mp.release();
598        }catch (Exception e){
599            Log.v(TAG,e.getMessage());
600            return false;
601        }
602        return true;
603    }
604
605
606    public static boolean isLooping(String filePath) {
607        MediaPlayer mp = null;
608
609        try {
610            mp = new MediaPlayer();
611            if (mp.isLooping()) {
612                Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor");
613                return false;
614            }
615            mp.setDataSource(filePath);
616            mp.prepare();
617
618            mp.setLooping(true);
619            if (!mp.isLooping()) {
620                Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
621                return false;
622            }
623
624            mp.setLooping(false);
625            if (mp.isLooping()) {
626                Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
627                return false;
628            }
629        }catch (Exception e){
630            Log.v(TAG, "Exception : " + e.toString());
631            return false;
632        } finally {
633            if (mp != null)
634                mp.release();
635        }
636
637        return true;
638    }
639
640    public static boolean isLoopingAfterReset(String filePath) {
641        MediaPlayer mp = null;
642        try {
643            mp = new MediaPlayer();
644            mp.setDataSource(filePath);
645            mp.prepare();
646
647            mp.setLooping(true);
648            mp.reset();
649            if (mp.isLooping()) {
650                Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()");
651                return false;
652            }
653        }catch (Exception e){
654            Log.v(TAG, "Exception : " + e.toString());
655            return false;
656        } finally {
657            if (mp != null)
658                mp.release();
659        }
660
661        return true;
662    }
663
664    /*
665     * Initializes the message looper so that the mediaPlayer object can
666     * receive the callback messages.
667     */
668    private static void initializeMessageLooper() {
669        Log.v(TAG, "start looper");
670        new Thread() {
671            @Override
672            public void run() {
673                // Set up a looper to be used by camera.
674                Looper.prepare();
675                Log.v(TAG, "start loopRun");
676                // Save the looper so that we can terminate this thread
677                // after we are done with it.
678                mLooper = Looper.myLooper();
679                mMediaPlayer = new MediaPlayer();
680                synchronized (lock) {
681                    mInitialized = true;
682                    lock.notify();
683                }
684                Looper.loop();  // Blocks forever until Looper.quit() is called.
685                Log.v(TAG, "initializeMessageLooper: quit.");
686            }
687        }.start();
688    }
689
690    /*
691     * Terminates the message looper thread.
692     */
693    private static void terminateMessageLooper() {
694        mLooper.quit();
695        mMediaPlayer.release();
696    }
697
698    static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
699        public void onPrepared(MediaPlayer mp) {
700            synchronized (prepareDone) {
701                if(mPrepareReset){
702                    Log.v(TAG, "call Reset");
703                    mMediaPlayer.reset();
704                }
705                Log.v(TAG, "notify the prepare callback");
706                prepareDone.notify();
707                onPrepareSuccess = true;
708            }
709        }
710    };
711
712    public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
713        //Added the PrepareReset flag which allow us to switch to different
714        //test case.
715        if (reset){
716            mPrepareReset = true;
717        }
718
719        synchronized (lock) {
720            initializeMessageLooper();
721            try {
722                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
723            } catch(Exception e) {
724                Log.v(TAG, "looper was interrupted.");
725                return false;
726            }
727        }
728        try{
729            mMediaPlayer.setOnPreparedListener(mPreparedListener);
730            mMediaPlayer.setDataSource(filePath);
731            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
732            mMediaPlayer.prepareAsync();
733            synchronized (prepareDone) {
734                try {
735                    prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
736                } catch (Exception e) {
737                    Log.v(TAG, "wait was interrupted.");
738                }
739            }
740            terminateMessageLooper();
741        }catch (Exception e){
742            Log.v(TAG,e.getMessage());
743        }
744       return onPrepareSuccess;
745    }
746
747    static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
748        public void onCompletion(MediaPlayer mp) {
749            synchronized (onCompletion) {
750                Log.v(TAG, "notify the completion callback");
751                onCompletion.notify();
752                onCompleteSuccess = true;
753            }
754        }
755    };
756
757    static MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
758        public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
759            mPlaybackError = true;
760            mp.reset();
761            return true;
762        }
763    };
764
765    static MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
766        public boolean onInfo(MediaPlayer mp, int what, int extra) {
767            switch (what){
768                case MediaPlayer.MEDIA_INFO_UNKNOWN:
769                    mMediaInfoUnknownCount++;
770                    break;
771                case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
772                    mMediaInfoVideoTrackLaggingCount++;
773                    break;
774                case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
775                    mMediaInfoBadInterleavingCount++;
776                    break;
777                case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
778                    mMediaInfoNotSeekableCount++;
779                    break;
780                case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
781                    mMediaInfoMetdataUpdateCount++;
782                    break;
783            }
784            return true;
785        }
786    };
787
788    public static boolean playMediaSamples(String filePath) throws Exception {
789        return playMediaSamples(filePath, 2000);
790    }
791
792    // For each media file, forward twice and backward once, then play to the end
793    public static boolean playMediaSamples(String filePath, int buffertime) throws Exception {
794        int duration = 0;
795        int curPosition = 0;
796        int nextPosition = 0;
797        int waittime = 0;
798        onCompleteSuccess = false;
799        mMediaInfoUnknownCount = 0;
800        mMediaInfoVideoTrackLaggingCount = 0;
801        mMediaInfoBadInterleavingCount = 0;
802        mMediaInfoNotSeekableCount = 0;
803        mMediaInfoMetdataUpdateCount = 0;
804        mPlaybackError = false;
805        mFailedToCompleteWithNoError = true;
806        String testResult;
807
808        initializeMessageLooper();
809        synchronized (lock) {
810            try {
811                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
812            } catch(Exception e) {
813                Log.v(TAG, "looper was interrupted.");
814                return false;
815            }
816        }
817        try {
818            mMediaPlayer.setOnCompletionListener(mCompletionListener);
819            mMediaPlayer.setOnErrorListener(mOnErrorListener);
820            mMediaPlayer.setOnInfoListener(mInfoListener);
821            Log.v(TAG, "playMediaSamples: sample file name " + filePath);
822            mMediaPlayer.setDataSource(filePath);
823            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
824            mMediaPlayer.prepare();
825            duration = mMediaPlayer.getDuration();
826            // start to play
827            mMediaPlayer.start();
828            if (duration < 0) {
829                Log.w(TAG, filePath + " has unknown duration, waiting until playback completes");
830                while (mMediaPlayer.isPlaying()) {
831                    SystemClock.sleep(1000);
832                }
833            } else {
834                waittime = duration - mMediaPlayer.getCurrentPosition();
835                synchronized(onCompletion){
836                    try {
837                        onCompletion.wait(waittime + buffertime);
838                    } catch (Exception e) {
839                        Log.v(TAG, "playMediaSamples are interrupted");
840                        return false;
841                    }
842                }
843            }
844            terminateMessageLooper();
845        } catch (Exception e) {
846            Log.v(TAG, "playMediaSamples:" + e.getMessage());
847        }
848        // Check if playback state is unknown (neither completed nor erroneous) unless
849        // it's not interrupted in the middle. If true, that is an exceptional case to investigate.
850        mFailedToCompleteWithNoError = !(onCompleteSuccess || mPlaybackError);
851        return onCompleteSuccess;
852    }
853}
854