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.stub.R; 20 21 22 import android.app.Activity; 23 import android.app.Instrumentation; 24 import android.content.Context; 25 import android.cts.util.PollingCheck; 26 import android.media.MediaPlayer; 27 import android.media.MediaPlayer.OnCompletionListener; 28 import android.media.MediaPlayer.OnErrorListener; 29 import android.media.MediaPlayer.OnPreparedListener; 30 import android.test.ActivityInstrumentationTestCase2; 31 import android.view.View.MeasureSpec; 32 import android.widget.MediaController; 33 import android.widget.VideoView; 34 35 import java.io.IOException; 36 import java.io.InputStream; 37 import java.io.OutputStream; 38 39 /** 40 * Test {@link VideoView}. 41 */ 42 public class VideoViewTest extends ActivityInstrumentationTestCase2<VideoViewStubActivity> { 43 /** The maximum time to wait for an operation. */ 44 private static final long TIME_OUT = 15000L; 45 /** The interval time to wait for completing an operation. */ 46 private static final long OPERATION_INTERVAL = 1500L; 47 /** The duration of R.raw.testvideo. */ 48 private static final int TEST_VIDEO_DURATION = 11047; 49 /** The full name of R.raw.testvideo. */ 50 private static final String VIDEO_NAME = "testvideo.3gp"; 51 /** delta for duration in case user uses different decoders on different 52 hardware that report a duration that's different by a few milliseconds */ 53 private static final int DURATION_DELTA = 100; 54 55 private VideoView mVideoView; 56 private Activity mActivity; 57 private Instrumentation mInstrumentation; 58 private String mVideoPath; 59 private MediaController mMediaController; 60 61 private static class MockListener { 62 private boolean mTriggered; 63 64 MockListener() { 65 mTriggered = false; 66 } 67 68 public boolean isTriggered() { 69 return mTriggered; 70 } 71 72 protected void onEvent() { 73 mTriggered = true; 74 } 75 } 76 77 private static class MockOnPreparedListener extends MockListener 78 implements OnPreparedListener { 79 public void onPrepared(MediaPlayer mp) { 80 super.onEvent(); 81 } 82 } 83 84 private static class MockOnErrorListener extends MockListener implements OnErrorListener { 85 public boolean onError(MediaPlayer mp, int what, int extra) { 86 super.onEvent(); 87 return false; 88 } 89 } 90 91 private static class MockOnCompletionListener extends MockListener 92 implements OnCompletionListener { 93 public void onCompletion(MediaPlayer mp) { 94 super.onEvent(); 95 } 96 } 97 98 /** 99 * Instantiates a new video view test. 100 */ 101 public VideoViewTest() { 102 super("com.android.cts.stub", VideoViewStubActivity.class); 103 } 104 105 /** 106 * Find the video view specified by id. 107 * 108 * @param id the id 109 * @return the video view 110 */ 111 private VideoView findVideoViewById(int id) { 112 return (VideoView) mActivity.findViewById(id); 113 } 114 115 private String prepareSampleVideo() throws IOException { 116 InputStream source = null; 117 OutputStream target = null; 118 119 try { 120 source = mActivity.getResources().openRawResource(R.raw.testvideo); 121 target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_WORLD_READABLE); 122 123 final byte[] buffer = new byte[1024]; 124 for (int len = source.read(buffer); len > 0; len = source.read(buffer)) { 125 target.write(buffer, 0, len); 126 } 127 } finally { 128 if (source != null) { 129 source.close(); 130 } 131 if (target != null) { 132 target.close(); 133 } 134 } 135 136 return mActivity.getFileStreamPath(VIDEO_NAME).getAbsolutePath(); 137 } 138 139 /** 140 * Wait for an asynchronous media operation complete. 141 * @throws InterruptedException 142 */ 143 private void waitForOperationComplete() throws InterruptedException { 144 Thread.sleep(OPERATION_INTERVAL); 145 } 146 147 @Override 148 protected void setUp() throws Exception { 149 super.setUp(); 150 mActivity = getActivity(); 151 mInstrumentation = getInstrumentation(); 152 mVideoPath = prepareSampleVideo(); 153 assertNotNull(mVideoPath); 154 mVideoView = findVideoViewById(R.id.videoview); 155 mMediaController = new MediaController(mActivity); 156 mVideoView.setMediaController(mMediaController); 157 } 158 159 public void testConstructor() { 160 new VideoView(mActivity); 161 162 new VideoView(mActivity, null); 163 164 new VideoView(mActivity, null, 0); 165 } 166 167 public void testPlayVideo1() throws Throwable { 168 final MockOnPreparedListener preparedListener = new MockOnPreparedListener(); 169 mVideoView.setOnPreparedListener(preparedListener); 170 final MockOnCompletionListener completionListener = new MockOnCompletionListener(); 171 mVideoView.setOnCompletionListener(completionListener); 172 173 runTestOnUiThread(new Runnable() { 174 public void run() { 175 mVideoView.setVideoPath(mVideoPath); 176 } 177 }); 178 new PollingCheck(TIME_OUT) { 179 @Override 180 protected boolean check() { 181 return preparedListener.isTriggered(); 182 } 183 }.run(); 184 assertFalse(completionListener.isTriggered()); 185 186 runTestOnUiThread(new Runnable() { 187 public void run() { 188 mVideoView.start(); 189 } 190 }); 191 // wait time is longer than duration in case system is sluggish 192 new PollingCheck(mVideoView.getDuration() + TIME_OUT) { 193 @Override 194 protected boolean check() { 195 return completionListener.isTriggered(); 196 } 197 }.run(); 198 } 199 200 public void testSetOnErrorListener() throws Throwable { 201 final MockOnErrorListener listener = new MockOnErrorListener(); 202 mVideoView.setOnErrorListener(listener); 203 204 runTestOnUiThread(new Runnable() { 205 public void run() { 206 String path = "unknown path"; 207 mVideoView.setVideoPath(path); 208 mVideoView.start(); 209 } 210 }); 211 mInstrumentation.waitForIdleSync(); 212 213 new PollingCheck(TIME_OUT) { 214 @Override 215 protected boolean check() { 216 return listener.isTriggered(); 217 } 218 }.run(); 219 } 220 221 public void testGetBufferPercentage() throws Throwable { 222 final MockOnPreparedListener prepareListener = new MockOnPreparedListener(); 223 mVideoView.setOnPreparedListener(prepareListener); 224 225 runTestOnUiThread(new Runnable() { 226 public void run() { 227 mVideoView.setVideoPath(mVideoPath); 228 } 229 }); 230 mInstrumentation.waitForIdleSync(); 231 232 new PollingCheck(TIME_OUT) { 233 @Override 234 protected boolean check() { 235 return prepareListener.isTriggered(); 236 } 237 }.run(); 238 int percent = mVideoView.getBufferPercentage(); 239 assertTrue(percent >= 0 && percent <= 100); 240 } 241 242 public void testResolveAdjustedSize() { 243 mVideoView = new VideoView(mActivity); 244 245 final int desiredSize = 100; 246 int resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.UNSPECIFIED); 247 assertEquals(desiredSize, resolvedSize); 248 249 final int specSize = MeasureSpec.getSize(MeasureSpec.AT_MOST); 250 resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.AT_MOST); 251 assertEquals(Math.min(desiredSize, specSize), resolvedSize); 252 253 resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.EXACTLY); 254 assertEquals(specSize, resolvedSize); 255 } 256 257 public void testGetDuration() throws Throwable { 258 runTestOnUiThread(new Runnable() { 259 public void run() { 260 mVideoView.setVideoPath(mVideoPath); 261 } 262 }); 263 waitForOperationComplete(); 264 assertTrue(Math.abs(mVideoView.getDuration() - TEST_VIDEO_DURATION) < DURATION_DELTA); 265 } 266 267 public void testSetMediaController() { 268 final MediaController ctlr = new MediaController(mActivity); 269 mVideoView.setMediaController(ctlr); 270 } 271 } 272