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.CameraActivity; 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 <CameraActivity> { 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(CameraActivity.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 testCancel() throws Exception { 109 setActivityIntent(mIntent); 110 getActivity(); 111 112 pressCancel(); 113 114 assertTrue(getActivity().isFinishing()); 115 assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); 116 } 117 118 @LargeTest 119 public void testRecordCancel() throws Exception { 120 setActivityIntent(mIntent); 121 getActivity(); 122 123 recordVideo(); 124 pressCancel(); 125 126 assertTrue(getActivity().isFinishing()); 127 assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); 128 } 129 130 @LargeTest 131 public void testExtraSizeLimit() throws Exception { 132 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 133 final long sizeLimit = 500000; // bytes 134 135 Uri uri = Uri.fromFile(mFile); 136 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 137 mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit); 138 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // use low quality to speed up 139 setActivityIntent(mIntent); 140 getActivity(); 141 142 recordVideo(5000); 143 pressDone(); 144 145 verify(getActivity(), uri); 146 long length = mFile.length(); 147 Log.v(TAG, "Video size is " + length + " bytes."); 148 assertTrue(length > 0); 149 assertTrue("Actual size=" + length, length <= sizeLimit); 150 } 151 152 @LargeTest 153 public void testExtraDurationLimit() throws Exception { 154 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 155 final int durationLimit = 2; // seconds 156 157 Uri uri = Uri.fromFile(mFile); 158 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 159 mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit); 160 setActivityIntent(mIntent); 161 getActivity(); 162 163 recordVideo(5000); 164 pressDone(); 165 166 int duration = verify(getActivity(), uri); 167 // The duraion should be close to to the limit. The last video duration 168 // also has duration, so the total duration may exceeds the limit a 169 // little bit. 170 Log.v(TAG, "Video length is " + duration + " ms."); 171 assertTrue(duration < (durationLimit + 1) * 1000); 172 } 173 174 @LargeTest 175 public void testExtraVideoQuality() throws Exception { 176 mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); 177 mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp"); 178 179 Uri uri = Uri.fromFile(mFile); 180 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 181 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality 182 setActivityIntent(mIntent); 183 getActivity(); 184 185 recordVideo(); 186 pressDone(); 187 188 verify(getActivity(), uri); 189 setActivity(null); 190 191 uri = Uri.fromFile(mFile2); 192 mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 193 mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality 194 setActivityIntent(mIntent); 195 getActivity(); 196 197 recordVideo(); 198 pressDone(); 199 200 verify(getActivity(), uri); 201 assertTrue(mFile.length() <= mFile2.length()); 202 } 203 204 // Verify result code, result data, and the duration. 205 private int verify(CameraActivity activity, Uri uri) throws Exception { 206 assertTrue(activity.isFinishing()); 207 assertEquals(Activity.RESULT_OK, activity.getResultCode()); 208 209 // Verify the video file 210 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 211 retriever.setDataSource(activity, uri); 212 String duration = retriever.extractMetadata( 213 MediaMetadataRetriever.METADATA_KEY_DURATION); 214 assertNotNull(duration); 215 int durationValue = Integer.parseInt(duration); 216 Log.v(TAG, "Video duration is " + durationValue); 217 assertTrue(durationValue > 0); 218 return durationValue; 219 } 220 221 private void recordVideo(int ms) throws Exception { 222 getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA); 223 Thread.sleep(ms); 224 getInstrumentation().runOnMainSync(new Runnable() { 225 @Override 226 public void run() { 227 // If recording is in progress, stop it. Run these atomically in 228 // UI thread. 229 CameraActivity activity = getActivity(); 230 if (activity.isRecording()) { 231 activity.findViewById(R.id.shutter_button).performClick(); 232 } 233 } 234 }); 235 } 236 237 private void recordVideo() throws Exception { 238 recordVideo(2000); 239 } 240 241 private void pressDone() { 242 getInstrumentation().runOnMainSync(new Runnable() { 243 @Override 244 public void run() { 245 getActivity().findViewById(R.id.btn_done).performClick(); 246 } 247 }); 248 } 249 250 private void pressCancel() { 251 getInstrumentation().runOnMainSync(new Runnable() { 252 @Override 253 public void run() { 254 getActivity().findViewById(R.id.btn_cancel).performClick(); 255 } 256 }); 257 } 258 } 259