Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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.widget.cts;
     18 
     19 import com.android.cts.widget.R;
     20 
     21 import android.app.Activity;
     22 import android.app.Instrumentation;
     23 import android.content.Context;
     24 import android.cts.util.PollingCheck;
     25 import android.media.MediaCodecInfo;
     26 import android.media.MediaCodecList;
     27 import android.media.MediaPlayer;
     28 import android.media.MediaPlayer.OnCompletionListener;
     29 import android.media.MediaPlayer.OnErrorListener;
     30 import android.media.MediaPlayer.OnPreparedListener;
     31 import android.test.ActivityInstrumentationTestCase2;
     32 import android.test.UiThreadTest;
     33 import android.util.Log;
     34 import android.view.View.MeasureSpec;
     35 import android.widget.MediaController;
     36 import android.widget.VideoView;
     37 
     38 import java.io.IOException;
     39 import java.io.InputStream;
     40 import java.io.OutputStream;
     41 
     42 /**
     43  * Test {@link VideoView}.
     44  */
     45 public class VideoViewTest extends ActivityInstrumentationTestCase2<VideoViewCtsActivity> {
     46     /** Debug TAG. **/
     47     private static final String TAG = "VideoViewTest";
     48     /** The maximum time to wait for an operation. */
     49     private static final long   TIME_OUT = 15000L;
     50     /** The interval time to wait for completing an operation. */
     51     private static final long   OPERATION_INTERVAL  = 1500L;
     52     /** The duration of R.raw.testvideo. */
     53     private static final int    TEST_VIDEO_DURATION = 11047;
     54     /** The full name of R.raw.testvideo. */
     55     private static final String VIDEO_NAME   = "testvideo.3gp";
     56     /** The MIME type. */
     57     private static final String MIME_TYPE = "video/3gpp";
     58     /** delta for duration in case user uses different decoders on different
     59         hardware that report a duration that's different by a few milliseconds */
     60     private static final int DURATION_DELTA = 100;
     61 
     62     private VideoView mVideoView;
     63     private Activity mActivity;
     64     private Instrumentation mInstrumentation;
     65     private String mVideoPath;
     66 
     67     private static class MockListener {
     68         private boolean mTriggered;
     69 
     70         MockListener() {
     71             mTriggered = false;
     72         }
     73 
     74         public boolean isTriggered() {
     75             return mTriggered;
     76         }
     77 
     78         protected void onEvent() {
     79             mTriggered = true;
     80         }
     81     }
     82 
     83     private static class MockOnPreparedListener extends MockListener
     84             implements OnPreparedListener {
     85         public void onPrepared(MediaPlayer mp) {
     86             super.onEvent();
     87         }
     88     }
     89 
     90     private static class MockOnErrorListener extends MockListener implements OnErrorListener {
     91         public boolean onError(MediaPlayer mp, int what, int extra) {
     92             super.onEvent();
     93             return false;
     94         }
     95     }
     96 
     97     private static class MockOnCompletionListener extends MockListener
     98             implements OnCompletionListener {
     99         public void onCompletion(MediaPlayer mp) {
    100             super.onEvent();
    101         }
    102     }
    103 
    104     // TODO: Make a public method selectCodec() in common libraries (e.g. cts/libs/), to avoid
    105     // redundant function definitions in this and other media related test files.
    106     private static boolean hasCodec(String mimeType) {
    107         int numCodecs = MediaCodecList.getCodecCount();
    108 
    109         for (int i = 0; i < numCodecs; i++) {
    110             MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
    111 
    112             if (!codecInfo.isEncoder()) {
    113                 continue;
    114             }
    115 
    116             String[] types = codecInfo.getSupportedTypes();
    117             for (int j = 0; j < types.length; j++) {
    118                 if (types[j].equalsIgnoreCase(mimeType)) {
    119                     return true;
    120                 }
    121             }
    122         }
    123         return false;
    124     }
    125 
    126     /**
    127      * Instantiates a new video view test.
    128      */
    129     public VideoViewTest() {
    130         super("com.android.cts.widget", VideoViewCtsActivity.class);
    131     }
    132 
    133     /**
    134      * Find the video view specified by id.
    135      *
    136      * @param id the id
    137      * @return the video view
    138      */
    139     private VideoView findVideoViewById(int id) {
    140         return (VideoView) mActivity.findViewById(id);
    141     }
    142 
    143     private String prepareSampleVideo() throws IOException {
    144         InputStream source = null;
    145         OutputStream target = null;
    146 
    147         try {
    148             source = mActivity.getResources().openRawResource(R.raw.testvideo);
    149             target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_WORLD_READABLE);
    150 
    151             final byte[] buffer = new byte[1024];
    152             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
    153                 target.write(buffer, 0, len);
    154             }
    155         } finally {
    156             if (source != null) {
    157                 source.close();
    158             }
    159             if (target != null) {
    160                 target.close();
    161             }
    162         }
    163 
    164         return mActivity.getFileStreamPath(VIDEO_NAME).getAbsolutePath();
    165     }
    166 
    167     /**
    168      * Wait for an asynchronous media operation complete.
    169      * @throws InterruptedException
    170      */
    171     private void waitForOperationComplete() throws InterruptedException {
    172         Thread.sleep(OPERATION_INTERVAL);
    173     }
    174 
    175     @Override
    176     protected void setUp() throws Exception {
    177         super.setUp();
    178         mActivity = getActivity();
    179         mInstrumentation = getInstrumentation();
    180         mVideoPath = prepareSampleVideo();
    181         assertNotNull(mVideoPath);
    182         mVideoView = findVideoViewById(R.id.videoview);
    183     }
    184 
    185     private void makeVideoView() {
    186         mActivity.runOnUiThread(new Runnable() {
    187             public void run() {
    188                 MediaController mediaController = new MediaController(mActivity);
    189                 mVideoView.setMediaController(mediaController);
    190             }
    191         });
    192         mInstrumentation.waitForIdleSync();
    193     }
    194 
    195     @UiThreadTest
    196     public void testConstructor() {
    197         new VideoView(mActivity);
    198 
    199         new VideoView(mActivity, null);
    200 
    201         new VideoView(mActivity, null, 0);
    202     }
    203 
    204     public void testPlayVideo1() throws Throwable {
    205         makeVideoView();
    206         // Don't run the test if the codec isn't supported.
    207         if (!hasCodec(MIME_TYPE)) {
    208             Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testPlayVideo1.");
    209             return;
    210         }
    211 
    212         final MockOnPreparedListener preparedListener = new MockOnPreparedListener();
    213         mVideoView.setOnPreparedListener(preparedListener);
    214         final MockOnCompletionListener completionListener = new MockOnCompletionListener();
    215         mVideoView.setOnCompletionListener(completionListener);
    216 
    217         runTestOnUiThread(new Runnable() {
    218             public void run() {
    219                 mVideoView.setVideoPath(mVideoPath);
    220             }
    221         });
    222         new PollingCheck(TIME_OUT) {
    223             @Override
    224             protected boolean check() {
    225                 return preparedListener.isTriggered();
    226             }
    227         }.run();
    228         assertFalse(completionListener.isTriggered());
    229 
    230         runTestOnUiThread(new Runnable() {
    231             public void run() {
    232                 mVideoView.start();
    233             }
    234         });
    235         // wait time is longer than duration in case system is sluggish
    236         new PollingCheck(mVideoView.getDuration() + TIME_OUT) {
    237             @Override
    238             protected boolean check() {
    239                 return completionListener.isTriggered();
    240             }
    241         }.run();
    242     }
    243 
    244     public void testSetOnErrorListener() throws Throwable {
    245         makeVideoView();
    246         final MockOnErrorListener listener = new MockOnErrorListener();
    247         mVideoView.setOnErrorListener(listener);
    248 
    249         runTestOnUiThread(new Runnable() {
    250             public void run() {
    251                 String path = "unknown path";
    252                 mVideoView.setVideoPath(path);
    253                 mVideoView.start();
    254             }
    255         });
    256         mInstrumentation.waitForIdleSync();
    257 
    258         new PollingCheck(TIME_OUT) {
    259             @Override
    260             protected boolean check() {
    261                 return listener.isTriggered();
    262             }
    263         }.run();
    264     }
    265 
    266     public void testGetBufferPercentage() throws Throwable {
    267         makeVideoView();
    268         // Don't run the test if the codec isn't supported.
    269         if (!hasCodec(MIME_TYPE)) {
    270             Log.w(TAG, MIME_TYPE + " not supported. Return from testGetBufferPercentage.");
    271             return;
    272         }
    273 
    274         final MockOnPreparedListener prepareListener = new MockOnPreparedListener();
    275         mVideoView.setOnPreparedListener(prepareListener);
    276 
    277         runTestOnUiThread(new Runnable() {
    278             public void run() {
    279                 mVideoView.setVideoPath(mVideoPath);
    280             }
    281         });
    282         mInstrumentation.waitForIdleSync();
    283 
    284         new PollingCheck(TIME_OUT) {
    285             @Override
    286             protected boolean check() {
    287                 return prepareListener.isTriggered();
    288             }
    289         }.run();
    290         int percent = mVideoView.getBufferPercentage();
    291         assertTrue(percent >= 0 && percent <= 100);
    292     }
    293 
    294     @UiThreadTest
    295     public void testResolveAdjustedSize() {
    296         mVideoView = new VideoView(mActivity);
    297 
    298         final int desiredSize = 100;
    299         int resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.UNSPECIFIED);
    300         assertEquals(desiredSize, resolvedSize);
    301 
    302         final int specSize = MeasureSpec.getSize(MeasureSpec.AT_MOST);
    303         resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.AT_MOST);
    304         assertEquals(Math.min(desiredSize, specSize), resolvedSize);
    305 
    306         resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.EXACTLY);
    307         assertEquals(specSize, resolvedSize);
    308     }
    309 
    310     public void testGetDuration() throws Throwable {
    311         // Don't run the test if the codec isn't supported.
    312         if (!hasCodec(MIME_TYPE)) {
    313             Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testGetDuration.");
    314             return;
    315         }
    316 
    317         runTestOnUiThread(new Runnable() {
    318             public void run() {
    319                 mVideoView.setVideoPath(mVideoPath);
    320             }
    321         });
    322         waitForOperationComplete();
    323         assertTrue(Math.abs(mVideoView.getDuration() - TEST_VIDEO_DURATION) < DURATION_DELTA);
    324     }
    325 
    326     @UiThreadTest
    327     public void testSetMediaController() {
    328         final MediaController ctlr = new MediaController(mActivity);
    329         mVideoView.setMediaController(ctlr);
    330     }
    331 }
    332