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