1 /* 2 * Copyright (C) 2011 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 com.android.camera.functional; 18 19 import com.android.camera.VideoCamera; 20 import com.android.camera.R; 21 22 import android.app.Activity; 23 import android.content.ContentResolver; 24 import android.content.Intent; 25 import android.database.Cursor; 26 import android.media.MediaMetadataRetriever; 27 import android.net.Uri; 28 import android.os.Environment; 29 import android.provider.MediaStore; 30 import android.provider.MediaStore.Video.VideoColumns; 31 import android.test.ActivityInstrumentationTestCase2; 32 import android.test.suitebuilder.annotation.LargeTest; 33 import android.util.Log; 34 import android.view.KeyEvent; 35 36 import java.io.File; 37 38 public class VideoCaptureIntentTest extends ActivityInstrumentationTestCase2 <VideoCamera> { 39 private static final String TAG = "VideoCaptureIntentTest"; 40 private Intent mIntent; 41 private Uri mVideoUri; 42 private File mFile, mFile2; 43 44 public VideoCaptureIntentTest() { 45 super(VideoCamera.class); 46 } 47 48 @Override 49 protected void setUp() throws Exception { 50 super.setUp(); 51 mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 52 } 53 54 @Override 55 protected void tearDown() throws Exception { 56 if (mVideoUri != null) { 57 ContentResolver resolver = getActivity().getContentResolver(); 58 Uri query = mVideoUri.buildUpon().build(); 59 String[] projection = new String[] {VideoColumns.DATA}; 60 61 Cursor cursor = null; 62 try { 63 cursor = resolver.query(query, projection, null, null, null); 64 if (cursor != null && cursor.moveToFirst()) { 65 new File(cursor.getString(0)).delete(); 66 } 67 } finally { 68 if (cursor != null) cursor.close(); 69 } 70 71 resolver.delete(mVideoUri, null, null); 72 } 73 if (mFile != null) mFile.delete(); 74 if (mFile2 != null) mFile2.delete(); 75 super.tearDown(); 76 } 77 78 @LargeTest 79 public void testNoExtraOutput() throws Exception { 80 setActivityIntent(mIntent); 81 getActivity(); 82 83 recordVideo(); 84 pressDone(); 85 86 Intent resultData = getActivity().getResultData(); 87 mVideoUri = resultData.getData(); 88 assertNotNull(mVideoUri); 89 verify(getActivity(), mVideoUri); 90 } 91 92 @LargeTest 93 public void testExtraOutput() throws Exception { 94 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 95 96 Uri uri = Uri.fromFile(mFile); 97 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 98 setActivityIntent(mIntent); 99 getActivity(); 100 101 recordVideo(); 102 pressDone(); 103 104 verify(getActivity(), uri); 105 } 106 107 @LargeTest 108 public void testRetake() throws Exception { 109 setActivityIntent(mIntent); 110 getActivity(); 111 112 recordVideo(); 113 pressRetake(); 114 recordVideo(); 115 pressDone(); 116 117 Intent resultData = getActivity().getResultData(); 118 mVideoUri = resultData.getData(); 119 assertNotNull(mVideoUri); 120 verify(getActivity(), mVideoUri); 121 } 122 123 @LargeTest 124 public void testCancel() throws Exception { 125 setActivityIntent(mIntent); 126 getActivity(); 127 128 pressCancel(); 129 130 assertTrue(getActivity().isFinishing()); 131 assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); 132 } 133 134 @LargeTest 135 public void testRecordCancel() throws Exception { 136 setActivityIntent(mIntent); 137 getActivity(); 138 139 recordVideo(); 140 pressCancel(); 141 142 assertTrue(getActivity().isFinishing()); 143 assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); 144 } 145 146 @LargeTest 147 public void testExtraSizeLimit() throws Exception { 148 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 149 final long sizeLimit = 500000; // bytes 150 151 Uri uri = Uri.fromFile(mFile); 152 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 153 mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit); 154 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // use low quality to speed up 155 setActivityIntent(mIntent); 156 getActivity(); 157 158 recordVideo(5000); 159 pressDone(); 160 161 verify(getActivity(), uri); 162 long length = mFile.length(); 163 Log.v(TAG, "Video size is " + length + " bytes."); 164 assertTrue(length > 0); 165 assertTrue("Actual size=" + length, length <= sizeLimit); 166 } 167 168 @LargeTest 169 public void testExtraDurationLimit() throws Exception { 170 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 171 final int durationLimit = 2; // seconds 172 173 Uri uri = Uri.fromFile(mFile); 174 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 175 mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit); 176 setActivityIntent(mIntent); 177 getActivity(); 178 179 recordVideo(5000); 180 pressDone(); 181 182 int duration = verify(getActivity(), uri); 183 // The duraion should be close to to the limit. The last video duration 184 // also has duration, so the total duration may exceeds the limit a 185 // little bit. 186 Log.v(TAG, "Video length is " + duration + " ms."); 187 assertTrue(duration < (durationLimit + 1) * 1000); 188 } 189 190 @LargeTest 191 public void testExtraVideoQuality() throws Exception { 192 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 193 mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp"); 194 195 Uri uri = Uri.fromFile(mFile); 196 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 197 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality 198 setActivityIntent(mIntent); 199 getActivity(); 200 201 recordVideo(); 202 pressDone(); 203 204 verify(getActivity(), uri); 205 setActivity(null); 206 207 uri = Uri.fromFile(mFile2); 208 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 209 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality 210 setActivityIntent(mIntent); 211 getActivity(); 212 213 recordVideo(); 214 pressDone(); 215 216 verify(getActivity(), uri); 217 assertTrue(mFile.length() <= mFile2.length()); 218 } 219 220 // Verify result code, result data, and the duration. 221 private int verify(VideoCamera activity, Uri uri) throws Exception { 222 assertTrue(activity.isFinishing()); 223 assertEquals(Activity.RESULT_OK, activity.getResultCode()); 224 225 // Verify the video file 226 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 227 retriever.setDataSource(activity, uri); 228 String duration = retriever.extractMetadata( 229 MediaMetadataRetriever.METADATA_KEY_DURATION); 230 assertNotNull(duration); 231 int durationValue = Integer.parseInt(duration); 232 Log.v(TAG, "Video duration is " + durationValue); 233 assertTrue(durationValue > 0); 234 return durationValue; 235 } 236 237 private void recordVideo(int ms) throws Exception { 238 getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA); 239 Thread.sleep(ms); 240 getInstrumentation().runOnMainSync(new Runnable() { 241 @Override 242 public void run() { 243 // If recording is in progress, stop it. Run these atomically in 244 // UI thread. 245 if (getActivity().isRecording()) { 246 getActivity().findViewById(R.id.shutter_button).performClick(); 247 } 248 } 249 }); 250 } 251 252 private void recordVideo() throws Exception { 253 recordVideo(2000); 254 } 255 256 private void pressDone() { 257 getInstrumentation().runOnMainSync(new Runnable() { 258 @Override 259 public void run() { 260 getActivity().findViewById(R.id.btn_done).performClick(); 261 } 262 }); 263 } 264 265 private void pressRetake() { 266 getInstrumentation().runOnMainSync(new Runnable() { 267 @Override 268 public void run() { 269 getActivity().findViewById(R.id.btn_retake).performClick(); 270 } 271 }); 272 } 273 274 private void pressCancel() { 275 getInstrumentation().runOnMainSync(new Runnable() { 276 @Override 277 public void run() { 278 getActivity().findViewById(R.id.btn_cancel).performClick(); 279 } 280 }); 281 } 282 } 283