From ffa6237aed496373cd578ccdb9d2a47cde90e25d Mon Sep 17 00:00:00 2001 From: Doris Liu Date: Thu, 31 Jan 2013 19:03:48 -0800 Subject: Move tests from camera to gallery2 Change-Id: If9143fff7d22295a5ad3bb01c4b860d07c3ee1c9 --- .../android/camera/CameraLaunchPerformance.java | 47 ++++ .../src/com/android/camera/CameraTestRunner.java | 48 ++++ .../src/com/android/camera/StressTests.java | 47 ++++ tests_camera/src/com/android/camera/UnitTests.java | 35 +++ .../camera/activity/CameraActivityTest.java | 53 +++++ .../android/camera/activity/CameraTestCase.java | 246 ++++++++++++++++++++ .../com/android/camera/functional/CameraTest.java | 81 +++++++ .../camera/functional/ImageCaptureIntentTest.java | 148 ++++++++++++ .../camera/functional/VideoCaptureIntentTest.java | 258 +++++++++++++++++++++ .../android/camera/power/ImageAndVideoCapture.java | 116 +++++++++ .../com/android/camera/stress/CameraLatency.java | 149 ++++++++++++ .../com/android/camera/stress/CameraStartUp.java | 157 +++++++++++++ .../camera/stress/CameraStressTestRunner.java | 61 +++++ .../com/android/camera/stress/ImageCapture.java | 121 ++++++++++ .../android/camera/stress/ShotToShotLatency.java | 143 ++++++++++++ .../com/android/camera/stress/SwitchPreview.java | 117 ++++++++++ .../src/com/android/camera/stress/TestUtil.java | 57 +++++ .../com/android/camera/stress/VideoCapture.java | 115 +++++++++ .../android/camera/unittest/CameraUnitTest.java | 107 +++++++++ 19 files changed, 2106 insertions(+) create mode 100644 tests_camera/src/com/android/camera/CameraLaunchPerformance.java create mode 100755 tests_camera/src/com/android/camera/CameraTestRunner.java create mode 100755 tests_camera/src/com/android/camera/StressTests.java create mode 100644 tests_camera/src/com/android/camera/UnitTests.java create mode 100644 tests_camera/src/com/android/camera/activity/CameraActivityTest.java create mode 100644 tests_camera/src/com/android/camera/activity/CameraTestCase.java create mode 100644 tests_camera/src/com/android/camera/functional/CameraTest.java create mode 100644 tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java create mode 100644 tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java create mode 100755 tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java create mode 100755 tests_camera/src/com/android/camera/stress/CameraLatency.java create mode 100644 tests_camera/src/com/android/camera/stress/CameraStartUp.java create mode 100755 tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java create mode 100755 tests_camera/src/com/android/camera/stress/ImageCapture.java create mode 100644 tests_camera/src/com/android/camera/stress/ShotToShotLatency.java create mode 100755 tests_camera/src/com/android/camera/stress/SwitchPreview.java create mode 100644 tests_camera/src/com/android/camera/stress/TestUtil.java create mode 100755 tests_camera/src/com/android/camera/stress/VideoCapture.java create mode 100644 tests_camera/src/com/android/camera/unittest/CameraUnitTest.java (limited to 'tests_camera/src') diff --git a/tests_camera/src/com/android/camera/CameraLaunchPerformance.java b/tests_camera/src/com/android/camera/CameraLaunchPerformance.java new file mode 100644 index 000000000..fe2b7761a --- /dev/null +++ b/tests_camera/src/com/android/camera/CameraLaunchPerformance.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.app.Activity; +import android.os.Bundle; +import android.test.LaunchPerformanceBase; + +/** + * Instrumentation class for Camera launch performance testing. + */ +public class CameraLaunchPerformance extends LaunchPerformanceBase { + @SuppressWarnings("unused") + private static final String TAG = "CameraLaunchPerformance"; + + @Override + public void onCreate(Bundle arguments) { + super.onCreate(arguments); + mIntent.setClassName(getTargetContext(), + "com.android.camera.CameraActivity"); + start(); + } + + /** + * Calls LaunchApp and finish. + */ + @Override + public void onStart() { + super.onStart(); + LaunchApp(); + finish(Activity.RESULT_OK, mResults); + } +} diff --git a/tests_camera/src/com/android/camera/CameraTestRunner.java b/tests_camera/src/com/android/camera/CameraTestRunner.java new file mode 100755 index 000000000..96c48a4c8 --- /dev/null +++ b/tests_camera/src/com/android/camera/CameraTestRunner.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.test.InstrumentationTestRunner; +import android.test.InstrumentationTestSuite; + +import com.android.camera.activity.CameraActivityTest; +import com.android.camera.functional.CameraTest; +import com.android.camera.functional.ImageCaptureIntentTest; +import com.android.camera.functional.VideoCaptureIntentTest; +import com.android.camera.unittest.CameraUnitTest; + +import junit.framework.TestSuite; + + +public class CameraTestRunner extends InstrumentationTestRunner { + + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(CameraActivityTest.class); + suite.addTestSuite(CameraTest.class); + suite.addTestSuite(ImageCaptureIntentTest.class); + suite.addTestSuite(VideoCaptureIntentTest.class); + suite.addTestSuite(CameraUnitTest.class); + return suite; + } + + @Override + public ClassLoader getLoader() { + return CameraTestRunner.class.getClassLoader(); + } +} diff --git a/tests_camera/src/com/android/camera/StressTests.java b/tests_camera/src/com/android/camera/StressTests.java new file mode 100755 index 000000000..7ed8317cc --- /dev/null +++ b/tests_camera/src/com/android/camera/StressTests.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import com.android.camera.stress.ImageCapture; +import com.android.camera.stress.SwitchPreview; +import com.android.camera.stress.CameraLatency; +import com.android.camera.stress.CameraStartUp; + +import junit.framework.Test; +import junit.framework.TestSuite; + + +/** + * Instrumentation Test Runner for all Camera tests. + * + * Running all tests: + * + * adb shell am instrument \ + * -e class com.android.camera.StressTests \ + * -w com.android.camera.tests/com.android.camera.stress.CameraStressTestRunner + */ + +public class StressTests extends TestSuite { + public static Test suite() { + TestSuite result = new TestSuite(); + result.addTestSuite(SwitchPreview.class); + result.addTestSuite(ImageCapture.class); + result.addTestSuite(CameraLatency.class); + result.addTestSuite(CameraStartUp.class); + return result; + } +} diff --git a/tests_camera/src/com/android/camera/UnitTests.java b/tests_camera/src/com/android/camera/UnitTests.java new file mode 100644 index 000000000..e56a907f0 --- /dev/null +++ b/tests_camera/src/com/android/camera/UnitTests.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.test.suitebuilder.UnitTestSuiteBuilder; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * TestSuite for all Camera unit tests. + */ +public class UnitTests extends TestSuite { + + public static Test suite() { + return new UnitTestSuiteBuilder(UnitTests.class) + .includePackages("com.android.camera.unittest") + .named("Camera Unit Tests") + .build(); + } +} diff --git a/tests_camera/src/com/android/camera/activity/CameraActivityTest.java b/tests_camera/src/com/android/camera/activity/CameraActivityTest.java new file mode 100644 index 000000000..cc8ed83c3 --- /dev/null +++ b/tests_camera/src/com/android/camera/activity/CameraActivityTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.activity; + +import android.hardware.Camera.Parameters; +import android.test.suitebuilder.annotation.LargeTest; + +import com.android.camera.CameraActivity; +import com.android.camera.CameraHolder; +import com.android.camera.R; + +import static com.google.testing.littlemock.LittleMock.doReturn; + +public class CameraActivityTest extends CameraTestCase { + public CameraActivityTest() { + super(CameraActivity.class); + } + + @LargeTest + public void testFailToConnect() throws Exception { + super.internalTestFailToConnect(); + } + + @LargeTest + public void testTakePicture() throws Exception { + CameraHolder.injectMockCamera(mCameraInfo, mOneMockCamera); + + getActivity(); + getInstrumentation().waitForIdleSync(); + + // Press shutter button to take a picture. + performClick(R.id.shutter_button); + getInstrumentation().waitForIdleSync(); + + // Force the activity to finish. + getActivity().finish(); + getInstrumentation().waitForIdleSync(); + } +} diff --git a/tests_camera/src/com/android/camera/activity/CameraTestCase.java b/tests_camera/src/com/android/camera/activity/CameraTestCase.java new file mode 100644 index 000000000..7c7c38daf --- /dev/null +++ b/tests_camera/src/com/android/camera/activity/CameraTestCase.java @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.activity; + +import android.app.Activity; +import android.app.Instrumentation; +import android.hardware.Camera; +import android.hardware.Camera.AutoFocusCallback; +import android.hardware.Camera.CameraInfo; +import android.hardware.Camera.Parameters; +import android.hardware.Camera.PictureCallback; +import android.hardware.Camera.ShutterCallback; +import android.test.ActivityInstrumentationTestCase2; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; + +import com.android.camera.CameraHolder; +import com.android.camera.CameraManager.CameraProxy; +import com.android.camera.R; +import com.android.camera.Util; + +import static com.google.testing.littlemock.LittleMock.mock; +import static com.google.testing.littlemock.LittleMock.doAnswer; +import static com.google.testing.littlemock.LittleMock.doReturn; +import static com.google.testing.littlemock.LittleMock.anyObject; +import com.google.testing.littlemock.AppDataDirGuesser; +import com.google.testing.littlemock.ArgumentCaptor; +import com.google.testing.littlemock.Captor; +import com.google.testing.littlemock.LittleMock; +import com.google.testing.littlemock.Mock; + +import java.io.File; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.concurrent.Callable; + + +public class CameraTestCase extends ActivityInstrumentationTestCase2 { + protected CameraInfo mCameraInfo[]; + protected CameraProxy mMockCamera[]; + protected CameraInfo mOneCameraInfo[]; + protected CameraProxy mOneMockCamera[]; + private static Parameters mParameters; + private byte[] mBlankJpeg; + @Mock private CameraProxy mMockBackCamera; + @Mock private CameraProxy mMockFrontCamera; + @Captor private ArgumentCaptor mShutterCallback; + @Captor private ArgumentCaptor mRawPictureCallback; + @Captor private ArgumentCaptor mJpegPictureCallback; + @Captor private ArgumentCaptor mAutoFocusCallback; + Callable mAutoFocusCallable = new AutoFocusCallable(); + Callable mTakePictureCallable = new TakePictureCallable(); + + private class TakePictureCallable implements Callable { + @Override + public Object call() throws Exception { + Runnable runnable = new Runnable() { + @Override + public void run() { + readBlankJpeg(); + Camera camera = mOneMockCamera[0].getCamera(); + mShutterCallback.getValue().onShutter(); + mRawPictureCallback.getValue().onPictureTaken(null, camera); + mJpegPictureCallback.getValue().onPictureTaken(mBlankJpeg, camera); + } + }; + // Probably need some delay. Make sure shutter callback is called + // after onShutterButtonFocus(false). + getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50); + return null; + } + } + + private class AutoFocusCallable implements Callable { + @Override + public Object call() throws Exception { + Runnable runnable = new Runnable() { + @Override + public void run() { + Camera camera = mOneMockCamera[0].getCamera(); + mAutoFocusCallback.getValue().onAutoFocus(true, camera); + } + }; + // Need some delay. Otherwise, focus callback will be run before + // onShutterButtonClick + getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50); + return null; + } + } + + public CameraTestCase(Class activityClass) { + super(activityClass); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + AppDataDirGuesser.setInstance(new AppDataDirGuesser() { + @Override + public File guessSuitableDirectoryForGeneratedClasses() { + return getInstrumentation().getTargetContext().getCacheDir(); + } + }); + AppDataDirGuesser.getsInstance().guessSuitableDirectoryForGeneratedClasses(); + LittleMock.initMocks(this); + mCameraInfo = new CameraInfo[2]; + mCameraInfo[0] = new CameraInfo(); + mCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK; + mCameraInfo[1] = new CameraInfo(); + mCameraInfo[1].facing = CameraInfo.CAMERA_FACING_FRONT; + mMockCamera = new CameraProxy[2]; + mMockCamera[0] = mMockBackCamera; + mMockCamera[1] = mMockFrontCamera; + doReturn(getParameters()).when(mMockCamera[0]).getParameters(); + doReturn(getParameters()).when(mMockCamera[1]).getParameters(); + + mOneCameraInfo = new CameraInfo[1]; + mOneCameraInfo[0] = new CameraInfo(); + mOneCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK; + mOneMockCamera = new CameraProxy[1]; + mOneMockCamera[0] = mMockBackCamera; + doReturn(getParameters()).when(mOneMockCamera[0]).getParameters(); + + // Mock takePicture call. + doAnswer(mTakePictureCallable).when(mMockBackCamera).takePicture( + mShutterCallback.capture(), mRawPictureCallback.capture(), + (PictureCallback) anyObject(), mJpegPictureCallback.capture()); + + // Mock autoFocus call. + doAnswer(mAutoFocusCallable).when(mMockBackCamera).autoFocus( + mAutoFocusCallback.capture()); + } + + private void readBlankJpeg() { + InputStream ins = getActivity().getResources().openRawResource(R.raw.blank); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + int size = 0; + + // Read the entire resource into a local byte buffer. + byte[] buffer = new byte[1024]; + try { + while((size = ins.read(buffer, 0, 1024)) >= 0){ + outputStream.write(buffer, 0, size); + } + } catch (IOException e) { + // ignore + } finally { + Util.closeSilently(ins); + } + mBlankJpeg = outputStream.toByteArray(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + CameraHolder.injectMockCamera(null, null); + } + + protected void internalTestFailToConnect() throws Exception { + CameraHolder.injectMockCamera(mCameraInfo, null); + + getActivity(); + Instrumentation inst = getInstrumentation(); + inst.waitForIdleSync(); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); // close dialog + } + + protected void performClick(final int id) { + Activity activity = getActivity(); + getInstrumentation().waitForIdleSync(); + assertNotNull(activity.findViewById(id)); + Instrumentation inst = getInstrumentation(); + inst.runOnMainSync(new Runnable() { + @Override + public void run() { + View v = getActivity().findViewById(id); + float x = (v.getLeft() + v.getRight()) / 2; + float y = (v.getTop() + v.getBottom()) / 2; + MotionEvent down = MotionEvent.obtain(0, 0, + MotionEvent.ACTION_DOWN, x, y, 0, 0, 0, 0, 0, 0, 0); + MotionEvent up = MotionEvent.obtain(0, 0, + MotionEvent.ACTION_UP, x, y, 0, 0, 0, 0, 0, 0, 0); + View parent = (View) v.getParent(); + parent.dispatchTouchEvent(down); + parent.dispatchTouchEvent(up); + } + }); + inst.waitForIdleSync(); + } + + protected void assertViewNotExist(int id) { + Activity activity = getActivity(); + getInstrumentation().waitForIdleSync(); + assertNull(activity.findViewById(id)); + } + + protected void assertViewNotVisible(int id) { + Activity activity = getActivity(); + getInstrumentation().waitForIdleSync(); + View view = activity.findViewById(id); + assertTrue(view.getVisibility() != View.VISIBLE); + } + + protected static Parameters getParameters() { + synchronized (CameraTestCase.class) { + if (mParameters == null) { + mParameters = android.hardware.Camera.getEmptyParameters(); + mParameters.unflatten("preview-format-values=yuv420sp,yuv420p,yuv422i-yuyv,yuv420p;" + + "preview-format=yuv420sp;" + + "preview-size-values=800x480;preview-size=800x480;" + + "picture-size-values=320x240;picture-size=320x240;" + + "jpeg-thumbnail-size-values=320x240,0x0;jpeg-thumbnail-width=320;jpeg-thumbnail-height=240;" + + "jpeg-thumbnail-quality=60;jpeg-quality=95;" + + "preview-frame-rate-values=30,15;preview-frame-rate=30;" + + "focus-mode-values=continuous-video,auto,macro,infinity,continuous-picture;focus-mode=auto;" + + "preview-fps-range-values=(15000,30000);preview-fps-range=15000,30000;" + + "scene-mode-values=auto,action,night;scene-mode=auto;" + + "flash-mode-values=off,on,auto,torch;flash-mode=off;" + + "whitebalance-values=auto,daylight,fluorescent,incandescent;whitebalance=auto;" + + "effect-values=none,mono,sepia;effect=none;" + + "zoom-supported=true;zoom-ratios=100,200,400;max-zoom=2;" + + "picture-format-values=jpeg;picture-format=jpeg;" + + "min-exposure-compensation=-30;max-exposure-compensation=30;" + + "exposure-compensation=0;exposure-compensation-step=0.1;" + + "horizontal-view-angle=40;vertical-view-angle=40;"); + } + } + return mParameters; + } +} diff --git a/tests_camera/src/com/android/camera/functional/CameraTest.java b/tests_camera/src/com/android/camera/functional/CameraTest.java new file mode 100644 index 000000000..3fdebc030 --- /dev/null +++ b/tests_camera/src/com/android/camera/functional/CameraTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.functional; + +import com.android.camera.CameraActivity; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Environment; +import android.os.Process; +import android.provider.MediaStore; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.LargeTest; + +import java.io.File; +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +public class CameraTest extends InstrumentationTestCase { + @LargeTest + public void testVideoCaptureIntentFdLeak() throws Exception { + Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse("file://" + + Environment.getExternalStorageDirectory().toString() + + "test_fd_leak.3gp")); + getInstrumentation().startActivitySync(intent).finish(); + // Test if the fd is closed. + for (File f: new File("/proc/" + Process.myPid() + "/fd").listFiles()) { + assertEquals(-1, f.getCanonicalPath().indexOf("test_fd_leak.3gp")); + } + } + + @LargeTest + public void testActivityLeak() throws Exception { + checkActivityLeak(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); + checkActivityLeak(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + } + + private void checkActivityLeak(String action) throws Exception { + final int TEST_COUNT = 5; + Intent intent = new Intent(action); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setClass(getInstrumentation().getTargetContext(), + CameraActivity.class); + ArrayList> refs = + new ArrayList>(); + for (int i = 0; i < TEST_COUNT; i++) { + Activity activity = getInstrumentation().startActivitySync(intent); + refs.add(new WeakReference(activity)); + activity.finish(); + getInstrumentation().waitForIdleSync(); + activity = null; + } + Runtime.getRuntime().gc(); + Runtime.getRuntime().runFinalization(); + Runtime.getRuntime().gc(); + int refCount = 0; + for (WeakReference c: refs) { + if (c.get() != null) refCount++; + } + // If applications are leaking activity, every reference is reachable. + assertTrue(refCount != TEST_COUNT); + } +} diff --git a/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java b/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java new file mode 100644 index 000000000..620ff50b0 --- /dev/null +++ b/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.functional; + +import com.android.camera.CameraActivity; +import com.android.camera.R; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.view.KeyEvent; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; + +public class ImageCaptureIntentTest extends ActivityInstrumentationTestCase2 { + private Intent mIntent; + + public ImageCaptureIntentTest() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + } + + @LargeTest + public void testNoExtraOutput() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + takePicture(); + pressDone(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_OK, getActivity().getResultCode()); + Intent resultData = getActivity().getResultData(); + Bitmap bitmap = (Bitmap) resultData.getParcelableExtra("data"); + assertNotNull(bitmap); + assertTrue(bitmap.getWidth() > 0); + assertTrue(bitmap.getHeight() > 0); + } + + @LargeTest + public void testExtraOutput() throws Exception { + File file = new File(Environment.getExternalStorageDirectory(), + "test.jpg"); + BufferedInputStream stream = null; + byte[] jpegData; + + try { + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); + setActivityIntent(mIntent); + getActivity(); + + takePicture(); + pressDone(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_OK, getActivity().getResultCode()); + + // Verify the jpeg file + int fileLength = (int) file.length(); + assertTrue(fileLength > 0); + jpegData = new byte[fileLength]; + stream = new BufferedInputStream(new FileInputStream(file)); + stream.read(jpegData); + } finally { + if (stream != null) stream.close(); + file.delete(); + } + + Bitmap b = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length); + assertTrue(b.getWidth() > 0); + assertTrue(b.getHeight() > 0); + } + + @LargeTest + public void testCancel() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + pressCancel(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); + } + + @LargeTest + public void testSnapshotCancel() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + takePicture(); + pressCancel(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); + } + + private void takePicture() throws Exception { + getInstrumentation().sendKeySync( + new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS)); + getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA); + Thread.sleep(4000); + } + + private void pressDone() { + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + getActivity().findViewById(R.id.btn_done).performClick(); + } + }); + } + + private void pressCancel() { + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + getActivity().findViewById(R.id.btn_cancel).performClick(); + } + }); + } +} diff --git a/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java b/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java new file mode 100644 index 000000000..292543ccf --- /dev/null +++ b/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.functional; + +import com.android.camera.CameraActivity; +import com.android.camera.R; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Intent; +import android.database.Cursor; +import android.media.MediaMetadataRetriever; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.provider.MediaStore.Video.VideoColumns; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; +import android.view.KeyEvent; + +import java.io.File; + +public class VideoCaptureIntentTest extends ActivityInstrumentationTestCase2 { + private static final String TAG = "VideoCaptureIntentTest"; + private Intent mIntent; + private Uri mVideoUri; + private File mFile, mFile2; + + public VideoCaptureIntentTest() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + } + + @Override + protected void tearDown() throws Exception { + if (mVideoUri != null) { + ContentResolver resolver = getActivity().getContentResolver(); + Uri query = mVideoUri.buildUpon().build(); + String[] projection = new String[] {VideoColumns.DATA}; + + Cursor cursor = null; + try { + cursor = resolver.query(query, projection, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + new File(cursor.getString(0)).delete(); + } + } finally { + if (cursor != null) cursor.close(); + } + + resolver.delete(mVideoUri, null, null); + } + if (mFile != null) mFile.delete(); + if (mFile2 != null) mFile2.delete(); + super.tearDown(); + } + + @LargeTest + public void testNoExtraOutput() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + recordVideo(); + pressDone(); + + Intent resultData = getActivity().getResultData(); + mVideoUri = resultData.getData(); + assertNotNull(mVideoUri); + verify(getActivity(), mVideoUri); + } + + @LargeTest + public void testExtraOutput() throws Exception { + mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); + + Uri uri = Uri.fromFile(mFile); + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + setActivityIntent(mIntent); + getActivity(); + + recordVideo(); + pressDone(); + + verify(getActivity(), uri); + } + + @LargeTest + public void testCancel() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + pressCancel(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); + } + + @LargeTest + public void testRecordCancel() throws Exception { + setActivityIntent(mIntent); + getActivity(); + + recordVideo(); + pressCancel(); + + assertTrue(getActivity().isFinishing()); + assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode()); + } + + @LargeTest + public void testExtraSizeLimit() throws Exception { + mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); + final long sizeLimit = 500000; // bytes + + Uri uri = Uri.fromFile(mFile); + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit); + mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // use low quality to speed up + setActivityIntent(mIntent); + getActivity(); + + recordVideo(5000); + pressDone(); + + verify(getActivity(), uri); + long length = mFile.length(); + Log.v(TAG, "Video size is " + length + " bytes."); + assertTrue(length > 0); + assertTrue("Actual size=" + length, length <= sizeLimit); + } + + @LargeTest + public void testExtraDurationLimit() throws Exception { + mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); + final int durationLimit = 2; // seconds + + Uri uri = Uri.fromFile(mFile); + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit); + setActivityIntent(mIntent); + getActivity(); + + recordVideo(5000); + pressDone(); + + int duration = verify(getActivity(), uri); + // The duraion should be close to to the limit. The last video duration + // also has duration, so the total duration may exceeds the limit a + // little bit. + Log.v(TAG, "Video length is " + duration + " ms."); + assertTrue(duration < (durationLimit + 1) * 1000); + } + + @LargeTest + public void testExtraVideoQuality() throws Exception { + mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp"); + mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp"); + + Uri uri = Uri.fromFile(mFile); + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality + setActivityIntent(mIntent); + getActivity(); + + recordVideo(); + pressDone(); + + verify(getActivity(), uri); + setActivity(null); + + uri = Uri.fromFile(mFile2); + mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality + setActivityIntent(mIntent); + getActivity(); + + recordVideo(); + pressDone(); + + verify(getActivity(), uri); + assertTrue(mFile.length() <= mFile2.length()); + } + + // Verify result code, result data, and the duration. + private int verify(CameraActivity activity, Uri uri) throws Exception { + assertTrue(activity.isFinishing()); + assertEquals(Activity.RESULT_OK, activity.getResultCode()); + + // Verify the video file + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + retriever.setDataSource(activity, uri); + String duration = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_DURATION); + assertNotNull(duration); + int durationValue = Integer.parseInt(duration); + Log.v(TAG, "Video duration is " + durationValue); + assertTrue(durationValue > 0); + return durationValue; + } + + private void recordVideo(int ms) throws Exception { + getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA); + Thread.sleep(ms); + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + // If recording is in progress, stop it. Run these atomically in + // UI thread. + CameraActivity activity = getActivity(); + if (activity.isRecording()) { + activity.findViewById(R.id.shutter_button).performClick(); + } + } + }); + } + + private void recordVideo() throws Exception { + recordVideo(2000); + } + + private void pressDone() { + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + getActivity().findViewById(R.id.btn_done).performClick(); + } + }); + } + + private void pressCancel() { + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + getActivity().findViewById(R.id.btn_cancel).performClick(); + } + }); + } +} diff --git a/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java b/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java new file mode 100755 index 000000000..b89b764c3 --- /dev/null +++ b/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.power; + +import com.android.camera.CameraActivity; + +import android.app.Instrumentation; +import android.provider.MediaStore; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; +import android.view.KeyEvent; +import android.content.Intent; +/** + * Junit / Instrumentation test case for camera power measurement + * + * Running the test suite: + * + * adb shell am instrument \ + * -e com.android.camera.power.ImageAndVideoCapture \ + * -w com.android.camera.tests/android.test.InstrumentationTestRunner + * + */ + +public class ImageAndVideoCapture extends ActivityInstrumentationTestCase2 { + private String TAG = "ImageAndVideoCapture"; + private static final int TOTAL_NUMBER_OF_IMAGECAPTURE = 5; + private static final int TOTAL_NUMBER_OF_VIDEOCAPTURE = 5; + private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 1500; //1.5 sedconds + private static final long WAIT_FOR_VIDEO_CAPTURE_TO_BE_TAKEN = 10000; //10 seconds + private static final long WAIT_FOR_PREVIEW = 1500; //1.5 seconds + private static final long WAIT_FOR_STABLE_STATE = 2000; //2 seconds + + public ImageAndVideoCapture() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + getActivity(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + @LargeTest + public void testLaunchCamera() { + // This test case capture the baseline for the image preview. + try { + Thread.sleep(WAIT_FOR_STABLE_STATE); + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + assertTrue("testImageCaptureDoNothing", false); + } + } + + @LargeTest + public void testCapture5Image() { + // This test case will use the default camera setting + Instrumentation inst = getInstrumentation(); + try { + for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) { + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + } + Thread.sleep(WAIT_FOR_STABLE_STATE); + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + assertTrue("testImageCapture", false); + } + } + + @LargeTest + public void testCapture5Videos() { + // This test case will use the default camera setting + Instrumentation inst = getInstrumentation(); + try { + // Switch to the video mode + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + intent.setClass(getInstrumentation().getTargetContext(), + CameraActivity.class); + getActivity().startActivity(intent); + for (int i = 0; i < TOTAL_NUMBER_OF_VIDEOCAPTURE; i++) { + Thread.sleep(WAIT_FOR_PREVIEW); + // record a video + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); + Thread.sleep(WAIT_FOR_VIDEO_CAPTURE_TO_BE_TAKEN); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); + Thread.sleep(WAIT_FOR_PREVIEW); + } + Thread.sleep(WAIT_FOR_STABLE_STATE); + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + assertTrue("testVideoCapture", false); + } + } +} diff --git a/tests_camera/src/com/android/camera/stress/CameraLatency.java b/tests_camera/src/com/android/camera/stress/CameraLatency.java new file mode 100755 index 000000000..35ff717a1 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/CameraLatency.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import com.android.camera.CameraActivity; + +import android.app.Instrumentation; +import android.os.Environment; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; +import android.view.KeyEvent; + +import java.io.BufferedWriter; +import java.io.FileWriter; + +/** + * Junit / Instrumentation test case for camera test + * + */ + +public class CameraLatency extends ActivityInstrumentationTestCase2 { + private String TAG = "CameraLatency"; + private static final int TOTAL_NUMBER_OF_IMAGECAPTURE = 20; + private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 4000; + private static final String CAMERA_TEST_OUTPUT_FILE = + Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; + + private long mTotalAutoFocusTime; + private long mTotalShutterLag; + private long mTotalShutterToPictureDisplayedTime; + private long mTotalPictureDisplayedToJpegCallbackTime; + private long mTotalJpegCallbackFinishTime; + private long mAvgAutoFocusTime; + private long mAvgShutterLag = mTotalShutterLag; + private long mAvgShutterToPictureDisplayedTime; + private long mAvgPictureDisplayedToJpegCallbackTime; + private long mAvgJpegCallbackFinishTime; + + public CameraLatency() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + getActivity(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + @LargeTest + public void testImageCapture() { + Log.v(TAG, "start testImageCapture test"); + Instrumentation inst = getInstrumentation(); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN); + try { + for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) { + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + //skip the first measurement + if (i != 0) { + CameraActivity c = getActivity(); + + // if any of the latency var accessor methods return -1 then the + // camera is set to a different module other than PhotoModule so + // skip the shot and try again + if (c.getAutoFocusTime() != -1) { + mTotalAutoFocusTime += c.getAutoFocusTime(); + mTotalShutterLag += c.getShutterLag(); + mTotalShutterToPictureDisplayedTime += + c.getShutterToPictureDisplayedTime(); + mTotalPictureDisplayedToJpegCallbackTime += + c.getPictureDisplayedToJpegCallbackTime(); + mTotalJpegCallbackFinishTime += c.getJpegCallbackFinishTime(); + } + else { + i--; + continue; + } + } + } + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + } + //ToDO: yslau + //1) Need to get the baseline from the cupcake so that we can add the + //failure condition of the camera latency. + //2) Only count those number with succesful capture. Set the timer to invalid + //before capture and ignore them if the value is invalid + int numberofRun = TOTAL_NUMBER_OF_IMAGECAPTURE - 1; + mAvgAutoFocusTime = mTotalAutoFocusTime / numberofRun; + mAvgShutterLag = mTotalShutterLag / numberofRun; + mAvgShutterToPictureDisplayedTime = + mTotalShutterToPictureDisplayedTime / numberofRun; + mAvgPictureDisplayedToJpegCallbackTime = + mTotalPictureDisplayedToJpegCallbackTime / numberofRun; + mAvgJpegCallbackFinishTime = + mTotalJpegCallbackFinishTime / numberofRun; + + try { + FileWriter fstream = null; + fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true); + BufferedWriter out = new BufferedWriter(fstream); + out.write("Camera Latency : \n"); + out.write("Number of loop: " + TOTAL_NUMBER_OF_IMAGECAPTURE + "\n"); + out.write("Avg AutoFocus = " + mAvgAutoFocusTime + "\n"); + out.write("Avg mShutterLag = " + mAvgShutterLag + "\n"); + out.write("Avg mShutterToPictureDisplayedTime = " + + mAvgShutterToPictureDisplayedTime + "\n"); + out.write("Avg mPictureDisplayedToJpegCallbackTime = " + + mAvgPictureDisplayedToJpegCallbackTime + "\n"); + out.write("Avg mJpegCallbackFinishTime = " + + mAvgJpegCallbackFinishTime + "\n"); + out.close(); + fstream.close(); + } catch (Exception e) { + fail("Camera Latency write output to file"); + } + Log.v(TAG, "The Image capture wait time = " + + WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + Log.v(TAG, "Avg AutoFocus = " + mAvgAutoFocusTime); + Log.v(TAG, "Avg mShutterLag = " + mAvgShutterLag); + Log.v(TAG, "Avg mShutterToPictureDisplayedTime = " + + mAvgShutterToPictureDisplayedTime); + Log.v(TAG, "Avg mPictureDisplayedToJpegCallbackTime = " + + mAvgPictureDisplayedToJpegCallbackTime); + Log.v(TAG, "Avg mJpegCallbackFinishTime = " + mAvgJpegCallbackFinishTime); + } +} + diff --git a/tests_camera/src/com/android/camera/stress/CameraStartUp.java b/tests_camera/src/com/android/camera/stress/CameraStartUp.java new file mode 100644 index 000000000..94e9a9419 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/CameraStartUp.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import com.android.camera.CameraActivity; + +import android.app.Activity; +import android.app.Instrumentation; +import android.content.Intent; +import android.os.Environment; +import android.provider.MediaStore; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; + +import java.io.FileWriter; +import java.io.BufferedWriter; + +/** + * Test cases to measure the camera and video recorder startup time. + */ +public class CameraStartUp extends InstrumentationTestCase { + + private static final int TOTAL_NUMBER_OF_STARTUP = 20; + + private String TAG = "CameraStartUp"; + private static final String CAMERA_TEST_OUTPUT_FILE = + Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; + private static int WAIT_TIME_FOR_PREVIEW = 1500; //1.5 second + + private long launchCamera() { + long startupTime = 0; + try { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + long beforeStart = System.currentTimeMillis(); + Instrumentation inst = getInstrumentation(); + Activity cameraActivity = inst.startActivitySync(intent); + long cameraStarted = System.currentTimeMillis(); + Thread.sleep(WAIT_TIME_FOR_PREVIEW); + cameraActivity.finish(); + startupTime = cameraStarted - beforeStart; + Thread.sleep(1000); + Log.v(TAG, "camera startup time: " + startupTime); + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + fail("Fails to get the output file"); + } + return startupTime; + } + + private long launchVideo() { + long startupTime = 0; + + try { + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + long beforeStart = System.currentTimeMillis(); + Instrumentation inst = getInstrumentation(); + Activity recorderActivity = inst.startActivitySync(intent); + long cameraStarted = System.currentTimeMillis(); + recorderActivity.finish(); + startupTime = cameraStarted - beforeStart; + Log.v(TAG, "Video Startup Time = " + startupTime); + // wait for 1s to make sure it reach a clean stage + Thread.sleep(WAIT_TIME_FOR_PREVIEW); + Log.v(TAG, "video startup time: " + startupTime); + } catch (Exception e) { + Log.v(TAG, "Got exception", e); + fail("Fails to launch video output file"); + } + return startupTime; + } + + private void writeToOutputFile(long totalStartupTime, + String individualStartupTime, boolean firstStartUp, String Type) throws Exception { + // TODO (yslau) : Need to integrate the output data with central + // dashboard + try { + FileWriter fstream = null; + fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true); + BufferedWriter out = new BufferedWriter(fstream); + if (firstStartUp) { + out.write("First " + Type + " Startup: " + totalStartupTime + "\n"); + } else { + long averageStartupTime = totalStartupTime / (TOTAL_NUMBER_OF_STARTUP -1); + out.write(Type + "startup time: " + "\n"); + out.write("Number of loop: " + (TOTAL_NUMBER_OF_STARTUP -1) + "\n"); + out.write(individualStartupTime + "\n\n"); + out.write(Type + " average startup time: " + averageStartupTime + " ms\n\n"); + } + out.close(); + fstream.close(); + } catch (Exception e) { + fail("Camera write output to file"); + } + } + + @LargeTest + public void testLaunchVideo() throws Exception { + String individualStartupTime; + individualStartupTime = "Individual Video Startup Time = "; + long totalStartupTime = 0; + long startupTime = 0; + for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) { + if (i == 0) { + // Capture the first startup time individually + long firstStartUpTime = launchVideo(); + writeToOutputFile(firstStartUpTime, "na", true, "Video"); + } else { + startupTime = launchVideo(); + totalStartupTime += startupTime; + individualStartupTime += startupTime + " ,"; + } + } + Log.v(TAG, "totalStartupTime =" + totalStartupTime); + writeToOutputFile(totalStartupTime, individualStartupTime, false, "Video"); + } + + @LargeTest + public void testLaunchCamera() throws Exception { + String individualStartupTime; + individualStartupTime = "Individual Camera Startup Time = "; + long totalStartupTime = 0; + long startupTime = 0; + for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) { + if (i == 0) { + // Capture the first startup time individually + long firstStartUpTime = launchCamera(); + writeToOutputFile(firstStartUpTime, "na", true, "Camera"); + } else { + startupTime = launchCamera(); + totalStartupTime += startupTime; + individualStartupTime += startupTime + " ,"; + } + } + Log.v(TAG, "totalStartupTime =" + totalStartupTime); + writeToOutputFile(totalStartupTime, + individualStartupTime, false, "Camera"); + } +} diff --git a/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java b/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java new file mode 100755 index 000000000..4047da0a2 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import android.os.Bundle; +import android.test.InstrumentationTestRunner; +import android.test.InstrumentationTestSuite; +import junit.framework.TestSuite; + +public class CameraStressTestRunner extends InstrumentationTestRunner { + + // Default recorder settings + public static int mVideoDuration = 20000; // set default to 20 seconds + public static int mVideoIterations = 100; // set default to 100 videos + public static int mImageIterations = 100; // set default to 100 images + + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(ImageCapture.class); + suite.addTestSuite(VideoCapture.class); + return suite; + } + + @Override + public ClassLoader getLoader() { + return CameraStressTestRunner.class.getClassLoader(); + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + String video_iterations = (String) icicle.get("video_iterations"); + String image_iterations = (String) icicle.get("image_iterations"); + String video_duration = (String) icicle.get("video_duration"); + + if ( video_iterations != null ) { + mVideoIterations = Integer.parseInt(video_iterations); + } + if ( image_iterations != null) { + mImageIterations = Integer.parseInt(image_iterations); + } + if ( video_duration != null) { + mVideoDuration = Integer.parseInt(video_duration); + } + } +} diff --git a/tests_camera/src/com/android/camera/stress/ImageCapture.java b/tests_camera/src/com/android/camera/stress/ImageCapture.java new file mode 100755 index 000000000..ad06db188 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/ImageCapture.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import com.android.camera.CameraActivity; +import com.android.camera.stress.CameraStressTestRunner; + +import android.app.Instrumentation; +import android.content.Intent; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; +import android.view.KeyEvent; +import android.app.Activity; + +/** + * Junit / Instrumentation test case for camera test + * + * Running the test suite: + * + * adb shell am instrument \ + * -e class com.android.camera.stress.ImageCapture \ + * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner + * + */ + +public class ImageCapture extends ActivityInstrumentationTestCase2 { + private String TAG = "ImageCapture"; + private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 1500; //1.5 sedconds + private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //3 seconds + + private TestUtil testUtil = new TestUtil(); + + // Private intent extras. + private final static String EXTRAS_CAMERA_FACING = + "android.intent.extras.CAMERA_FACING"; + + public ImageCapture() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + testUtil.prepareOutputFile(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + testUtil.closeOutputFile(); + super.tearDown(); + } + + public void captureImages(String reportTag, Instrumentation inst) { + int total_num_of_images = CameraStressTestRunner.mImageIterations; + Log.v(TAG, "no of images = " + total_num_of_images); + + //TODO(yslau): Need to integrate the outoput with the central dashboard, + //write to a txt file as a temp solution + boolean memoryResult = false; + KeyEvent focusEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS); + + try { + testUtil.writeReportHeader(reportTag, total_num_of_images); + for (int i = 0; i < total_num_of_images; i++) { + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + inst.sendKeySync(focusEvent); + inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA); + Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN); + testUtil.writeResult(i); + } + } catch (Exception e) { + Log.v(TAG, "Got exception: " + e.toString()); + assertTrue("testImageCapture", false); + } + } + + @LargeTest + public void testBackImageCapture() throws Exception { + Instrumentation inst = getInstrumentation(); + Intent intent = new Intent(); + + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRAS_CAMERA_FACING, + android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK); + Activity act = inst.startActivitySync(intent); + Thread.sleep(WAIT_FOR_SWITCH_CAMERA); + captureImages("Back Camera Image Capture\n", inst); + act.finish(); + } + + @LargeTest + public void testFrontImageCapture() throws Exception { + Instrumentation inst = getInstrumentation(); + Intent intent = new Intent(); + + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRAS_CAMERA_FACING, + android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT); + Activity act = inst.startActivitySync(intent); + Thread.sleep(WAIT_FOR_SWITCH_CAMERA); + captureImages("Front Camera Image Capture\n", inst); + act.finish(); + } +} diff --git a/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java b/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java new file mode 100644 index 000000000..0c1ef45b9 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import android.app.Instrumentation; +import android.os.Environment; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.util.Log; +import android.view.KeyEvent; +import com.android.camera.CameraActivity; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; + +/** + * Junit / Instrumentation test case for measuring camera shot to shot latency + */ +public class ShotToShotLatency extends ActivityInstrumentationTestCase2 { + private String TAG = "ShotToShotLatency"; + private static final int TOTAL_NUMBER_OF_SNAPSHOTS = 250; + private static final long SNAPSHOT_WAIT = 1000; + private static final String CAMERA_TEST_OUTPUT_FILE = + Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; + private static final String CAMERA_IMAGE_DIRECTORY = + Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/"; + + public ShotToShotLatency() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + getActivity(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + private void cleanupLatencyImages() { + try { + File sdcard = new File(CAMERA_IMAGE_DIRECTORY); + File[] pics = null; + FilenameFilter filter = new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".jpg"); + } + }; + pics = sdcard.listFiles(filter); + for (File f : pics) { + f.delete(); + } + } catch (SecurityException e) { + Log.e(TAG, "Security manager access violation: " + e.toString()); + } + } + + private void sleep(long time) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + Log.e(TAG, "Sleep InterruptedException " + e.toString()); + } + } + + @LargeTest + public void testShotToShotLatency() { + long sigmaOfDiffFromMeanSquared = 0; + double mean = 0; + double standardDeviation = 0; + ArrayList captureTimes = new ArrayList(); + ArrayList latencyTimes = new ArrayList(); + + Log.v(TAG, "start testShotToShotLatency test"); + Instrumentation inst = getInstrumentation(); + + // Generate data points + for (int i = 0; i < TOTAL_NUMBER_OF_SNAPSHOTS; i++) { + inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); + sleep(SNAPSHOT_WAIT); + CameraActivity c = getActivity(); + if (c.getCaptureStartTime() > 0) { + captureTimes.add(c.getCaptureStartTime()); + } + } + + // Calculate latencies + for (int j = 1; j < captureTimes.size(); j++) { + latencyTimes.add(captureTimes.get(j) - captureTimes.get(j - 1)); + } + + // Crunch numbers + for (long dataPoint : latencyTimes) { + mean += (double) dataPoint; + } + mean /= latencyTimes.size(); + + for (long dataPoint : latencyTimes) { + sigmaOfDiffFromMeanSquared += (dataPoint - mean) * (dataPoint - mean); + } + standardDeviation = Math.sqrt(sigmaOfDiffFromMeanSquared / latencyTimes.size()); + + // Report statistics + File outFile = new File(CAMERA_TEST_OUTPUT_FILE); + BufferedWriter output = null; + try { + output = new BufferedWriter(new FileWriter(outFile, true)); + output.write("Shot to shot latency - mean: " + mean + "\n"); + output.write("Shot to shot latency - standard deviation: " + standardDeviation + "\n"); + cleanupLatencyImages(); + } catch (IOException e) { + Log.e(TAG, "testShotToShotLatency IOException writing to log " + e.toString()); + } finally { + try { + if (output != null) { + output.close(); + } + } catch (IOException e) { + Log.e(TAG, "Error closing file: " + e.toString()); + } + } + } +} diff --git a/tests_camera/src/com/android/camera/stress/SwitchPreview.java b/tests_camera/src/com/android/camera/stress/SwitchPreview.java new file mode 100755 index 000000000..86b1b5d99 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/SwitchPreview.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import com.android.camera.CameraActivity; + +import android.app.Instrumentation; +import android.content.Intent; +import android.provider.MediaStore; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.os.Environment; +import android.util.Log; + +import java.io.BufferedWriter; +import java.io.FileWriter; + +/** + * Junit / Instrumentation test case for camera test + * + * Running the test suite: + * + * adb shell am instrument \ + * -e class com.android.camera.stress.SwitchPreview \ + * -w com.android.camera.tests/com.android.camera.stress.CameraStressTestRunner + * + */ +public class SwitchPreview extends ActivityInstrumentationTestCase2 { + private String TAG = "SwitchPreview"; + private static final int TOTAL_NUMBER_OF_SWITCHING = 200; + private static final long WAIT_FOR_PREVIEW = 4000; + + private static final String CAMERA_TEST_OUTPUT_FILE = + Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; + private BufferedWriter mOut; + private FileWriter mfstream; + + public SwitchPreview() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + getActivity(); + prepareOutputFile(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + getActivity().finish(); + closeOutputFile(); + super.tearDown(); + } + + private void prepareOutputFile(){ + try{ + mfstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true); + mOut = new BufferedWriter(mfstream); + } catch (Exception e){ + assertTrue("Camera Switch Mode", false); + } + } + + private void closeOutputFile() { + try { + mOut.write("\n"); + mOut.close(); + mfstream.close(); + } catch (Exception e) { + assertTrue("CameraSwitchMode close output", false); + } + } + + @LargeTest + public void testSwitchMode() { + //Switching the video and the video recorder mode + Instrumentation inst = getInstrumentation(); + try{ + mOut.write("Camera Switch Mode:\n"); + mOut.write("No of loops :" + TOTAL_NUMBER_OF_SWITCHING + "\n"); + mOut.write("loop: "); + for (int i=0; i< TOTAL_NUMBER_OF_SWITCHING; i++) { + Thread.sleep(WAIT_FOR_PREVIEW); + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.setClass(getInstrumentation().getTargetContext(), + CameraActivity.class); + getActivity().startActivity(intent); + Thread.sleep(WAIT_FOR_PREVIEW); + intent = new Intent(); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.setClass(getInstrumentation().getTargetContext(), + CameraActivity.class); + getActivity().startActivity(intent); + mOut.write(" ," + i); + mOut.flush(); + } + } catch (Exception e){ + Log.v(TAG, "Got exception", e); + } + } +} diff --git a/tests_camera/src/com/android/camera/stress/TestUtil.java b/tests_camera/src/com/android/camera/stress/TestUtil.java new file mode 100644 index 000000000..64e2039f2 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/TestUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import android.os.Environment; +import java.io.FileWriter; +import java.io.BufferedWriter; + + +/** + * Collection of utility functions used for the test. + */ +public class TestUtil { + public BufferedWriter mOut; + public FileWriter mfstream; + + public TestUtil() { + } + + public void prepareOutputFile() throws Exception { + String camera_test_output_file = + Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; + mfstream = new FileWriter(camera_test_output_file, true); + mOut = new BufferedWriter(mfstream); + } + + public void closeOutputFile() throws Exception { + mOut.write("\n"); + mOut.close(); + mfstream.close(); + } + + public void writeReportHeader(String reportTag, int iteration) throws Exception { + mOut.write(reportTag); + mOut.write("No of loops :" + iteration + "\n"); + mOut.write("loop: "); + } + + public void writeResult(int iteration) throws Exception { + mOut.write(" ," + iteration); + mOut.flush(); + } +} diff --git a/tests_camera/src/com/android/camera/stress/VideoCapture.java b/tests_camera/src/com/android/camera/stress/VideoCapture.java new file mode 100755 index 000000000..ec55ccce2 --- /dev/null +++ b/tests_camera/src/com/android/camera/stress/VideoCapture.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.stress; + +import com.android.camera.CameraActivity; +import com.android.camera.stress.TestUtil; + +import android.app.Activity; +import android.app.Instrumentation; +import android.content.Intent; +import android.provider.MediaStore; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; +import android.view.KeyEvent; + +import com.android.camera.stress.CameraStressTestRunner; + +/** + * Junit / Instrumentation test case for camera test + * + * Running the test suite: + * + * adb shell am instrument \ + * -e class com.android.camera.stress.VideoCapture \ + * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner + * + */ + +public class VideoCapture extends ActivityInstrumentationTestCase2 { + private static final long WAIT_FOR_PREVIEW = 1500; //1.5 seconds + private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //2 seconds + + // Private intent extras which control the camera facing. + private final static String EXTRAS_CAMERA_FACING = + "android.intent.extras.CAMERA_FACING"; + + private TestUtil testUtil = new TestUtil(); + + public VideoCapture() { + super(CameraActivity.class); + } + + @Override + protected void setUp() throws Exception { + testUtil.prepareOutputFile(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + testUtil.closeOutputFile(); + super.tearDown(); + } + + @LargeTest + public void captureVideos(String reportTag, Instrumentation inst) throws Exception{ + boolean memoryResult = false; + int total_num_of_videos = CameraStressTestRunner.mVideoIterations; + int video_duration = CameraStressTestRunner.mVideoDuration; + testUtil.writeReportHeader(reportTag, total_num_of_videos); + + for (int i = 0; i < total_num_of_videos; i++) { + Thread.sleep(WAIT_FOR_PREVIEW); + // record a video + inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA); + Thread.sleep(video_duration); + inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA); + testUtil.writeResult(i); + } + } + + @LargeTest + public void testBackVideoCapture() throws Exception { + Instrumentation inst = getInstrumentation(); + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRAS_CAMERA_FACING, + android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK); + Activity act = inst.startActivitySync(intent); + Thread.sleep(WAIT_FOR_SWITCH_CAMERA); + captureVideos("Back Camera Video Capture\n", inst); + act.finish(); + } + + @LargeTest + public void testFrontVideoCapture() throws Exception { + Instrumentation inst = getInstrumentation(); + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + + intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRAS_CAMERA_FACING, + android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT); + Activity act = inst.startActivitySync(intent); + Thread.sleep(WAIT_FOR_SWITCH_CAMERA); + captureVideos("Front Camera Video Capture\n", inst); + act.finish(); + } +} diff --git a/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java b/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java new file mode 100644 index 000000000..0b4fc80f6 --- /dev/null +++ b/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.unittest; + +import com.android.camera.Util; + +import android.graphics.Matrix; +import android.test.suitebuilder.annotation.SmallTest; + +import junit.framework.TestCase; + +@SmallTest +public class CameraUnitTest extends TestCase { + public void testRoundOrientation() { + int h = Util.ORIENTATION_HYSTERESIS; + assertEquals(0, Util.roundOrientation(0, 0)); + assertEquals(0, Util.roundOrientation(359, 0)); + assertEquals(0, Util.roundOrientation(0 + 44 + h, 0)); + assertEquals(90, Util.roundOrientation(0 + 45 + h, 0)); + assertEquals(0, Util.roundOrientation(360 - 44 - h, 0)); + assertEquals(270, Util.roundOrientation(360 - 45 - h, 0)); + + assertEquals(90, Util.roundOrientation(90, 90)); + assertEquals(90, Util.roundOrientation(90 + 44 + h, 90)); + assertEquals(180, Util.roundOrientation(90 + 45 + h, 90)); + assertEquals(90, Util.roundOrientation(90 - 44 - h, 90)); + assertEquals(0, Util.roundOrientation(90 - 45 - h, 90)); + + assertEquals(180, Util.roundOrientation(180, 180)); + assertEquals(180, Util.roundOrientation(180 + 44 + h, 180)); + assertEquals(270, Util.roundOrientation(180 + 45 + h, 180)); + assertEquals(180, Util.roundOrientation(180 - 44 - h, 180)); + assertEquals(90, Util.roundOrientation(180 - 45 - h, 180)); + + assertEquals(270, Util.roundOrientation(270, 270)); + assertEquals(270, Util.roundOrientation(270 + 44 + h, 270)); + assertEquals(0, Util.roundOrientation(270 + 45 + h, 270)); + assertEquals(270, Util.roundOrientation(270 - 44 - h, 270)); + assertEquals(180, Util.roundOrientation(270 - 45 - h, 270)); + + assertEquals(90, Util.roundOrientation(90, 0)); + assertEquals(180, Util.roundOrientation(180, 0)); + assertEquals(270, Util.roundOrientation(270, 0)); + + assertEquals(0, Util.roundOrientation(0, 90)); + assertEquals(180, Util.roundOrientation(180, 90)); + assertEquals(270, Util.roundOrientation(270, 90)); + + assertEquals(0, Util.roundOrientation(0, 180)); + assertEquals(90, Util.roundOrientation(90, 180)); + assertEquals(270, Util.roundOrientation(270, 180)); + + assertEquals(0, Util.roundOrientation(0, 270)); + assertEquals(90, Util.roundOrientation(90, 270)); + assertEquals(180, Util.roundOrientation(180, 270)); + } + + public void testPrepareMatrix() { + Matrix matrix = new Matrix(); + float[] points; + int[] expected; + + Util.prepareMatrix(matrix, false, 0, 800, 480); + points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250}; + expected = new int[] {0, 0, 400, 240, 800, 480, 400, 480, 100, 300}; + matrix.mapPoints(points); + assertEquals(expected, points); + + Util.prepareMatrix(matrix, false, 90, 800, 480); + points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250}; + expected = new int[] {800, 0, 400, 240, 0, 480, 0, 240, 300, 60}; + matrix.mapPoints(points); + assertEquals(expected, points); + + Util.prepareMatrix(matrix, false, 180, 800, 480); + points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250}; + expected = new int[] {800, 480, 400, 240, 0, 0, 400, 0, 700, 180}; + matrix.mapPoints(points); + assertEquals(expected, points); + + Util.prepareMatrix(matrix, true, 180, 800, 480); + points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250}; + expected = new int[] {0, 480, 400, 240, 800, 0, 400, 0, 100, 180}; + matrix.mapPoints(points); + assertEquals(expected, points); + } + + private void assertEquals(int expected[], float[] actual) { + for (int i = 0; i < expected.length; i++) { + assertEquals("Array index " + i + " mismatch", expected[i], Math.round(actual[i])); + } + } +} -- cgit v1.2.3