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