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