1 /*
2  * Copyright (C) 2012 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 
17 package android.mediastress.cts;
18 
19 import android.content.res.AssetFileDescriptor;
20 import android.graphics.Bitmap;
21 import android.graphics.BitmapFactory;
22 import android.media.MediaMetadataRetriever;
23 import android.media.MediaPlayer;
24 import android.media.MediaRecorder;
25 import android.os.Looper;
26 import android.os.SystemClock;
27 import android.util.Log;
28 
29 import java.io.IOException;
30 import java.io.InputStream;
31 
32 /**
33  * Junit / Instrumentation test case for the media player api
34  */
35 public class CodecTest {
36     private static String TAG = "CodecTest";
37     private static MediaPlayer mMediaPlayer;
38     private MediaPlayer.OnPreparedListener mOnPreparedListener;
39 
40     private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000;  //1 min max.
41     private static boolean mInitialized = false;
42     private static boolean mPrepareReset = false;
43     private static Looper mLooper = null;
44     private static final Object mLock = new Object();
45     private static final Object mPrepareDone = new Object();
46     private static final Object mVideoSizeChanged = new Object();
47     private static final Object mOnCompletion = new Object();
48     private static boolean mOnPrepareSuccess = false;
49     private static final long PAUSE_WAIT_TIME = 3000;
50     private static final long WAIT_TIME = 2000;
51     private static final int SEEK_TIME = 10000;
52 
53     public static boolean mOnCompleteSuccess = false;
54     public static boolean mPlaybackError = false;
55     public static int mMediaInfoUnknownCount = 0;
56     public static int mMediaInfoVideoTrackLaggingCount = 0;
57     public static int mMediaInfoBadInterleavingCount = 0;
58     public static int mMediaInfoNotSeekableCount = 0;
59     public static int mMediaInfoMetdataUpdateCount = 0;
60 
printCpuInfo()61     public static String printCpuInfo() {
62         String cm = "dumpsys cpuinfo";
63         String cpuinfo = null;
64         int ch;
65         try {
66             Process  p = Runtime.getRuntime().exec(cm);
67             InputStream in = p.getInputStream();
68             StringBuffer sb = new StringBuffer(512);
69             while ( ( ch = in.read() ) != -1 ) {
70                 sb.append((char) ch);
71             }
72             cpuinfo = sb.toString();
73         } catch (IOException e) {
74             Log.v(TAG, e.toString());
75         }
76         return cpuinfo;
77     }
78 
79 
getDuration(String filePath)80     public static int getDuration(String filePath) {
81         Log.v(TAG, "getDuration - " + filePath);
82         MediaPlayer mp = new MediaPlayer();
83         try {
84             mp.setDataSource(filePath);
85             mp.prepare();
86         } catch (Exception e) {
87             Log.v(TAG, e.toString());
88         }
89         int duration = mp.getDuration();
90         Log.v(TAG, "Duration " + duration);
91         mp.release();
92         Log.v(TAG, "release");
93         return duration;
94     }
95 
getCurrentPosition(String filePath)96     public static boolean getCurrentPosition(String filePath) {
97         Log.v(TAG, "GetCurrentPosition - " + filePath);
98         int currentPosition = 0;
99         long t1=0;
100         long t2 =0;
101         MediaPlayer mp = new MediaPlayer();
102         try {
103             mp.setDataSource(filePath);
104             Log.v(TAG, "start playback");
105             mp.prepare();
106             mp.start();
107             t1=SystemClock.uptimeMillis();
108             Thread.sleep(10000);
109             mp.pause();
110             Thread.sleep(PAUSE_WAIT_TIME);
111             t2=SystemClock.uptimeMillis();
112         } catch (Exception e) {
113             Log.v(TAG, e.toString());
114         }
115         currentPosition = mp.getCurrentPosition();
116         mp.stop();
117         mp.release();
118         Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
119 
120         if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
121             return true;
122         else
123             return false;
124     }
125 
seekTo(String filePath)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(SEEK_TIME);
135             Thread.sleep(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 > SEEK_TIME *0.8))
145             return true;
146         else
147             return false;
148     }
149 
setLooping(String filePath)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 
pause(String filePath)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(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 
prepareStopRelease(String filePath)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 
preparePauseRelease(String filePath)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 (mVideoSizeChanged) {
239                     Log.v(TAG, "sizechanged notification received ...");
240                     mVideoSizeChanged.notify();
241                 }
242             }
243     };
244 
245     //Register the videoSizeChanged listener
videoHeight(String filePath)246     public static int videoHeight(String filePath) throws Exception {
247         Log.v(TAG, "videoHeight - " + filePath);
248         int videoHeight = 0;
249         synchronized (mLock) {
250             initializeMessageLooper();
251             try {
252                 mLock.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.getSurfaceView().getHolder());
261             mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
262             synchronized (mVideoSizeChanged) {
263                 try {
264                     mMediaPlayer.prepare();
265                     mMediaPlayer.start();
266                     mVideoSizeChanged.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
videoWidth(String filePath)281     public static int videoWidth(String filePath) throws Exception {
282         Log.v(TAG, "videoWidth - " + filePath);
283         int videoWidth = 0;
284 
285         synchronized (mLock) {
286             initializeMessageLooper();
287             try {
288                 mLock.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.getSurfaceView().getHolder());
297             mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
298             synchronized (mVideoSizeChanged) {
299                 try {
300                     mMediaPlayer.prepare();
301                     mMediaPlayer.start();
302                     mVideoSizeChanged.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.
videoSeekTo(String filePath)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.getSurfaceView().getHolder());
325         mp.prepare();
326         mp.start();
327 
328         Thread.sleep(5000);
329         duration = mp.getDuration();
330         Log.v(TAG, "video duration " + duration);
331         mp.pause();
332         Thread.sleep(PAUSE_WAIT_TIME);
333         mp.seekTo(duration - 20000 );
334         mp.start();
335         Thread.sleep(1000);
336         mp.pause();
337         Thread.sleep(PAUSE_WAIT_TIME);
338         mp.seekTo(duration/2);
339         mp.start();
340         Thread.sleep(10000);
341         currentPosition = mp.getCurrentPosition();
342         Log.v(TAG, "video currentPosition " + currentPosition);
343         mp.release();
344         if (currentPosition > (duration /2 )*0.9)
345             return true;
346         else
347             return false;
348 
349     }
350 
seekToEnd(String filePath)351     public static boolean seekToEnd(String filePath) {
352         Log.v(TAG, "seekToEnd - " + filePath);
353         int duration = 0;
354         int currentPosition = 0;
355         boolean isPlaying = false;
356         MediaPlayer mp = new MediaPlayer();
357         try {
358             mp.setDataSource(filePath);
359             Log.v(TAG, "start playback");
360             mp.prepare();
361             duration = mp.getDuration();
362             mp.seekTo(duration - 3000);
363             mp.start();
364             Thread.sleep(6000);
365         } catch (Exception e) {}
366         isPlaying = mp.isPlaying();
367         currentPosition = mp.getCurrentPosition();
368         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
369         mp.stop();
370         mp.release();
371         Log.v(TAG, "duration = " + duration);
372         if (currentPosition < 0.9 * duration || isPlaying)
373             return false;
374         else
375             return true;
376     }
377 
shortMediaStop(String filePath)378     public static boolean shortMediaStop(String filePath) {
379         Log.v(TAG, "shortMediaStop - " + filePath);
380         //This test is only for the short media file
381         int duration = 0;
382         int currentPosition = 0;
383         boolean isPlaying = false;
384         MediaPlayer mp = new MediaPlayer();
385         try {
386             mp.setDataSource(filePath);
387             Log.v(TAG, "start playback");
388             mp.prepare();
389             duration = mp.getDuration();
390             mp.start();
391             Thread.sleep(10000);
392         } catch (Exception e) {}
393         isPlaying = mp.isPlaying();
394         currentPosition = mp.getCurrentPosition();
395         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
396         mp.stop();
397         mp.release();
398         Log.v(TAG, "duration = " + duration);
399         if (currentPosition > duration || isPlaying)
400             return false;
401         else
402             return true;
403     }
404 
playToEnd(String filePath)405     public static boolean playToEnd(String filePath) {
406         Log.v(TAG, "shortMediaStop - " + filePath);
407         //This test is only for the short media file
408         int duration = 200000;
409         int updateDuration = 0;
410         int currentPosition = 0;
411         boolean isPlaying = false;
412         MediaPlayer mp = new MediaPlayer();
413         try {
414             Thread.sleep(5000);
415             mp.setDataSource(filePath);
416             Log.v(TAG, "start playback");
417             mp.prepare();
418             //duration = mp.getDuration();
419             mp.start();
420             Thread.sleep(50000);
421         } catch (Exception e){}
422         isPlaying = mp.isPlaying();
423         currentPosition = mp.getCurrentPosition();
424         //updateDuration = mp.getDuration();
425         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
426         mp.stop();
427         mp.release();
428         //Log.v(TAG, "duration = " + duration);
429         //Log.v(TAG, "Update duration = " + updateDuration);
430         if (currentPosition > duration || isPlaying)
431             return false;
432         else
433             return true;
434     }
435 
seektoBeforeStart(String filePath)436     public static boolean seektoBeforeStart(String filePath){
437         Log.v(TAG, "seektoBeforeStart - " + filePath);
438         //This test is only for the short media file
439         int duration = 0;
440         int currentPosition = 0;
441 
442         MediaPlayer mp = new MediaPlayer();
443         try {
444             mp.setDataSource(filePath);
445             mp.prepare();
446             duration = mp.getDuration();
447             mp.seekTo(duration - 10000);
448             mp.start();
449             currentPosition=mp.getCurrentPosition();
450             mp.stop();
451             mp.release();
452         } catch (Exception e) {}
453         if (currentPosition < duration/2)
454             return false;
455         else
456             return true;
457     }
458 
mediaRecorderRecord(String filePath)459     public static boolean mediaRecorderRecord(String filePath){
460         Log.v(TAG, "SoundRecording - " + filePath);
461         //This test is only for the short media file
462         int duration = 0;
463         try {
464             MediaRecorder mRecorder = new MediaRecorder();
465             mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
466             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
467             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
468             mRecorder.setOutputFile(filePath);
469             mRecorder.prepare();
470             mRecorder.start();
471             Thread.sleep(500);
472             mRecorder.stop();
473             Log.v(TAG, "sound recorded");
474             mRecorder.release();
475         } catch (Exception e) {
476             Log.v(TAG, e.toString());
477         }
478 
479         //Verify the recorded file
480         MediaPlayer mp = new MediaPlayer();
481         try {
482             mp.setDataSource(filePath);
483             mp.prepare();
484             duration = mp.getDuration();
485             Log.v(TAG,"Duration " + duration);
486             mp.release();
487         } catch (Exception e) {}
488         //Check the record media file length is greate than zero
489         if (duration > 0)
490             return true;
491         else
492             return false;
493 
494     }
495 
496     //Test for mediaMeta Data Thumbnail
getThumbnail(String filePath, String goldenPath)497     public static boolean getThumbnail(String filePath, String goldenPath) {
498         Log.v(TAG, "getThumbnail - " + filePath);
499 
500         int goldenHeight = 0;
501         int goldenWidth = 0;
502         int outputWidth = 0;
503         int outputHeight = 0;
504 
505         //This test is only for the short media file
506         try {
507             BitmapFactory mBitmapFactory = new BitmapFactory();
508 
509             MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
510             try {
511                 mMediaMetadataRetriever.setDataSource(filePath);
512             } catch(Exception e) {
513                 e.printStackTrace();
514                 return false;
515             }
516             Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1);
517 
518             //Verify the thumbnail
519             Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
520             outputWidth = outThumbnail.getWidth();
521             outputHeight = outThumbnail.getHeight();
522             goldenHeight = goldenBitmap.getHeight();
523             goldenWidth = goldenBitmap.getWidth();
524 
525             //check the image dimension
526             if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight))
527                 return false;
528 
529             // Check half line of pixel
530             int x = goldenHeight / 2;
531             for (int j = 1; j < goldenWidth / 2; j++) {
532                 if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)) {
533                     Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j));
534                     return false;
535                 }
536            }
537         } catch (Exception e) {
538             Log.v(TAG, e.toString());
539             return false;
540         }
541         return true;
542     }
543 
544     //Load midi file from resources
resourcesPlayback(AssetFileDescriptor afd, int expectedDuration)545     public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration) {
546         int duration = 0;
547         try {
548             MediaPlayer mp = new MediaPlayer();
549             mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
550             mp.prepare();
551             mp.start();
552             duration = mp.getDuration();
553             Thread.sleep(5000);
554             mp.release();
555         } catch (Exception e) {
556             Log.v(TAG,e.getMessage());
557         }
558         if (duration > expectedDuration)
559             return true;
560         else
561             return false;
562     }
563 
prepareAsyncReset(String filePath)564     public static boolean prepareAsyncReset(String filePath) {
565         //preparesAsync
566         try {
567             MediaPlayer mp = new MediaPlayer();
568             mp.setDataSource(filePath);
569             mp.prepareAsync();
570             mp.reset();
571             mp.release();
572         } catch (Exception e) {
573             Log.v(TAG,e.getMessage());
574             return false;
575         }
576         return true;
577     }
578 
579 
isLooping(String filePath)580     public static boolean isLooping(String filePath) {
581         MediaPlayer mp = null;
582 
583         try {
584             mp = new MediaPlayer();
585             if (mp.isLooping()) {
586                 Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor");
587                 return false;
588             }
589             mp.setDataSource(filePath);
590             mp.prepare();
591 
592             mp.setLooping(true);
593             if (!mp.isLooping()) {
594                 Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
595                 return false;
596             }
597 
598             mp.setLooping(false);
599             if (mp.isLooping()) {
600                 Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
601                 return false;
602             }
603         } catch (Exception e) {
604             Log.v(TAG, "Exception : " + e.toString());
605             return false;
606         } finally {
607             if (mp != null)
608                 mp.release();
609         }
610 
611         return true;
612     }
613 
isLoopingAfterReset(String filePath)614     public static boolean isLoopingAfterReset(String filePath) {
615         MediaPlayer mp = null;
616         try {
617             mp = new MediaPlayer();
618             mp.setDataSource(filePath);
619             mp.prepare();
620 
621             mp.setLooping(true);
622             mp.reset();
623             if (mp.isLooping()) {
624                 Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()");
625                 return false;
626             }
627         } catch (Exception e){
628             Log.v(TAG, "Exception : " + e.toString());
629             return false;
630         } finally {
631             if (mp != null)
632                 mp.release();
633         }
634 
635         return true;
636     }
637 
638     /*
639      * Initializes the message looper so that the mediaPlayer object can
640      * receive the callback messages.
641      */
initializeMessageLooper()642     private static void initializeMessageLooper() {
643         Log.v(TAG, "start looper");
644         new Thread() {
645             @Override
646             public void run() {
647                 // Set up a looper to be used by camera.
648                 Looper.prepare();
649                 Log.v(TAG, "start loopRun");
650                 // Save the looper so that we can terminate this thread
651                 // after we are done with it.
652                 mLooper = Looper.myLooper();
653                 mMediaPlayer = new MediaPlayer();
654                 synchronized (mLock) {
655                     mInitialized = true;
656                     mLock.notify();
657                 }
658                 Looper.loop();  // Blocks forever until Looper.quit() is called.
659                 Log.v(TAG, "initializeMessageLooper: quit.");
660             }
661         }.start();
662     }
663 
664     /*
665      * Terminates the message looper thread.
666      */
terminateMessageLooper()667     private static void terminateMessageLooper() {
668         mLooper.quit();
669         mMediaPlayer.release();
670     }
671 
672     static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
673         public void onPrepared(MediaPlayer mp) {
674             synchronized (mPrepareDone) {
675                 if(mPrepareReset) {
676                     Log.v(TAG, "call Reset");
677                     mMediaPlayer.reset();
678                 }
679                 Log.v(TAG, "notify the prepare callback");
680                 mPrepareDone.notify();
681                 mOnPrepareSuccess = true;
682             }
683         }
684     };
685 
prepareAsyncCallback(String filePath, boolean reset)686     public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
687         //Added the PrepareReset flag which allow us to switch to different
688         //test case.
689         if (reset) {
690             mPrepareReset = true;
691         }
692 
693         synchronized (mLock) {
694             initializeMessageLooper();
695             try {
696                 mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
697             } catch(Exception e) {
698                 Log.v(TAG, "looper was interrupted.");
699                 return false;
700             }
701         }
702         try{
703             mMediaPlayer.setOnPreparedListener(mPreparedListener);
704             mMediaPlayer.setDataSource(filePath);
705             mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
706             mMediaPlayer.prepareAsync();
707             synchronized (mPrepareDone) {
708                 try {
709                     mPrepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
710                 } catch (Exception e) {
711                     Log.v(TAG, "wait was interrupted.");
712                 }
713             }
714             terminateMessageLooper();
715         }catch (Exception e) {
716             Log.v(TAG,e.getMessage());
717         }
718        return mOnPrepareSuccess;
719     }
720 
721     static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
722         public void onCompletion(MediaPlayer mp) {
723             synchronized (mOnCompletion) {
724                 Log.v(TAG, "notify the completion callback");
725                 mOnCompletion.notify();
726                 mOnCompleteSuccess = true;
727             }
728         }
729     };
730 
731     static MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
732         public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
733             Log.v(TAG, "playback error");
734             mPlaybackError = true;
735             mp.reset();
736             synchronized (mOnCompletion) {
737                 Log.v(TAG, "notify the completion callback");
738                 mOnCompletion.notify();
739                 mOnCompleteSuccess = false;
740             }
741             return true;
742         }
743     };
744 
745     static MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
746         public boolean onInfo(MediaPlayer mp, int what, int extra) {
747             switch (what) {
748                 case MediaPlayer.MEDIA_INFO_UNKNOWN:
749                     mMediaInfoUnknownCount++;
750                     break;
751                 case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
752                     mMediaInfoVideoTrackLaggingCount++;
753                     break;
754                 case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
755                     mMediaInfoBadInterleavingCount++;
756                     break;
757                 case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
758                     mMediaInfoNotSeekableCount++;
759                     break;
760                 case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
761                     mMediaInfoMetdataUpdateCount++;
762                     break;
763             }
764             return true;
765         }
766     };
767 
playMediaSample(String fileName)768     public static boolean playMediaSample(String fileName) throws Exception {
769         int duration = 0;
770         int curPosition = 0;
771         int nextPosition = 0;
772         int waittime = 0;
773         mOnCompleteSuccess = false;
774         mMediaInfoUnknownCount = 0;
775         mMediaInfoVideoTrackLaggingCount = 0;
776         mMediaInfoBadInterleavingCount = 0;
777         mMediaInfoNotSeekableCount = 0;
778         mMediaInfoMetdataUpdateCount = 0;
779         mPlaybackError = false;
780 
781         initializeMessageLooper();
782         synchronized (mLock) {
783             try {
784                 mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
785             } catch(Exception e) {
786                 Log.v(TAG, "looper was interrupted.");
787                 return false;
788             }
789         }
790         try {
791             mMediaPlayer.setOnCompletionListener(mCompletionListener);
792             mMediaPlayer.setOnErrorListener(mOnErrorListener);
793             mMediaPlayer.setOnInfoListener(mInfoListener);
794             Log.v(TAG, "playMediaSample: sample file name " + fileName);
795             mMediaPlayer.setDataSource(fileName);
796             mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
797             mMediaPlayer.prepare();
798             duration = mMediaPlayer.getDuration();
799             Log.v(TAG, "duration of media " + duration);
800             // start to play
801             mMediaPlayer.start();
802             waittime = duration - mMediaPlayer.getCurrentPosition();
803             synchronized(mOnCompletion) {
804                 try {
805                     mOnCompletion.wait(waittime + 2000);
806                 } catch (Exception e) {
807                     Log.v(TAG, "playMediaSamples are interrupted");
808                     return false;
809                 }
810             }
811             if (!mOnCompleteSuccess && !mPlaybackError) {
812                 Log.e(TAG, "wait timed-out without onCompletion notification");
813             }
814             terminateMessageLooper();
815         } catch (Exception e) {
816             Log.v(TAG, "playMediaSample Exception:" + e.getMessage());
817         }
818         return mOnCompleteSuccess;
819     }
820 }
821