1 /*
2  * Copyright (C) 2018 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 android.hardware.cts;
18 
19 import android.app.Instrumentation;
20 import android.graphics.SurfaceTexture;
21 import android.hardware.Camera;
22 import android.hardware.Camera.Parameters;
23 import android.hardware.cts.helpers.CameraUtils;
24 import android.os.SystemClock;
25 import android.util.Log;
26 
27 import androidx.test.InstrumentationRegistry;
28 
29 import com.android.compatibility.common.util.DeviceReportLog;
30 import com.android.compatibility.common.util.ResultType;
31 import com.android.compatibility.common.util.ResultUnit;
32 import com.android.compatibility.common.util.Stat;
33 
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.junit.runners.JUnit4;
39 
40 import java.util.Arrays;
41 
42 /**
43  * Measure and report legacy camera device performance.
44  */
45 @RunWith(JUnit4.class)
46 public class LegacyCameraPerformanceTest {
47     private static final String TAG = "CameraPerformanceTest";
48     private static final String REPORT_LOG_NAME = "CtsCamera1TestCases";
49     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
50 
51     private Instrumentation mInstrumentation;
52     private CameraPerformanceTestHelper mHelper;
53     private int[] mCameraIds;
54 
55     @Before
setUp()56     public void setUp() throws Exception {
57         mInstrumentation = InstrumentationRegistry.getInstrumentation();
58         mHelper = new CameraPerformanceTestHelper();
59         mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
60     }
61 
62     @After
tearDown()63     public void tearDown() throws Exception {
64         if (mHelper.getCamera() != null) {
65             mHelper.getCamera().release();
66         }
67     }
68 
69     @Test
testLegacyApiPerformance()70     public void testLegacyApiPerformance() throws Exception {
71         final int NUM_TEST_LOOPS = 10;
72         if (mCameraIds.length == 0) return;
73 
74         double[] avgCameraTakePictureTimes = new double[mCameraIds.length];
75 
76         int count = 0;
77         for (int id : mCameraIds) {
78             DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
79                     "test_camera_takePicture");
80             reportLog.addValue("camera_id", id, ResultType.NEUTRAL, ResultUnit.NONE);
81             double[] cameraOpenTimes = new double[NUM_TEST_LOOPS];
82             double[] startPreviewTimes = new double[NUM_TEST_LOOPS];
83             double[] stopPreviewTimes = new double[NUM_TEST_LOOPS];
84             double[] cameraCloseTimes = new double[NUM_TEST_LOOPS];
85             double[] cameraTakePictureTimes = new double[NUM_TEST_LOOPS];
86             double[] cameraAutoFocusTimes = new double[NUM_TEST_LOOPS];
87             boolean afSupported = false;
88             long openTimeMs, startPreviewTimeMs, stopPreviewTimeMs, closeTimeMs, takePictureTimeMs,
89                     autofocusTimeMs;
90 
91             for (int i = 0; i < NUM_TEST_LOOPS; i++) {
92                 openTimeMs = SystemClock.elapsedRealtime();
93                 mHelper.initializeMessageLooper(id);
94                 cameraOpenTimes[i] = SystemClock.elapsedRealtime() - openTimeMs;
95 
96                 Parameters parameters = mHelper.getCamera().getParameters();
97                 if (i == 0) {
98                     for (String focusMode: parameters.getSupportedFocusModes()) {
99                         if (Parameters.FOCUS_MODE_AUTO.equals(focusMode)) {
100                             afSupported = true;
101                             break;
102                         }
103                     }
104                 }
105 
106                 if (afSupported) {
107                     parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
108                     mHelper.getCamera().setParameters(parameters);
109                 }
110 
111                 SurfaceTexture previewTexture = new SurfaceTexture(/*random int*/ 1);
112                 mHelper.getCamera().setPreviewTexture(previewTexture);
113                 startPreviewTimeMs = SystemClock.elapsedRealtime();
114                 mHelper.startPreview();
115                 startPreviewTimes[i] = SystemClock.elapsedRealtime() - startPreviewTimeMs;
116 
117                 if (afSupported) {
118                     autofocusTimeMs = SystemClock.elapsedRealtime();
119                     mHelper.autoFocus();
120                     cameraAutoFocusTimes[i] = SystemClock.elapsedRealtime() - autofocusTimeMs;
121                 }
122 
123                 //Let preview run for a while
124                 Thread.sleep(1000);
125 
126                 takePictureTimeMs = SystemClock.elapsedRealtime();
127                 mHelper.takePicture();
128                 cameraTakePictureTimes[i] = SystemClock.elapsedRealtime() - takePictureTimeMs;
129 
130                 //Resume preview after image capture
131                 mHelper.startPreview();
132 
133                 stopPreviewTimeMs = SystemClock.elapsedRealtime();
134                 mHelper.getCamera().stopPreview();
135                 closeTimeMs = SystemClock.elapsedRealtime();
136                 stopPreviewTimes[i] = closeTimeMs - stopPreviewTimeMs;
137 
138                 mHelper.terminateMessageLooper();
139                 cameraCloseTimes[i] = SystemClock.elapsedRealtime() - closeTimeMs;
140                 previewTexture.release();
141             }
142 
143             if (VERBOSE) {
144                 Log.v(TAG, "Camera " + id + " device open times(ms): "
145                         + Arrays.toString(cameraOpenTimes)
146                         + ". Average(ms): " + Stat.getAverage(cameraOpenTimes)
147                         + ". Min(ms): " + Stat.getMin(cameraOpenTimes)
148                         + ". Max(ms): " + Stat.getMax(cameraOpenTimes));
149                 Log.v(TAG, "Camera " + id + " start preview times(ms): "
150                         + Arrays.toString(startPreviewTimes)
151                         + ". Average(ms): " + Stat.getAverage(startPreviewTimes)
152                         + ". Min(ms): " + Stat.getMin(startPreviewTimes)
153                         + ". Max(ms): " + Stat.getMax(startPreviewTimes));
154                 if (afSupported) {
155                     Log.v(TAG, "Camera " + id + " autofocus times(ms): "
156                             + Arrays.toString(cameraAutoFocusTimes)
157                             + ". Average(ms): " + Stat.getAverage(cameraAutoFocusTimes)
158                             + ". Min(ms): " + Stat.getMin(cameraAutoFocusTimes)
159                             + ". Max(ms): " + Stat.getMax(cameraAutoFocusTimes));
160                 }
161                 Log.v(TAG, "Camera " + id + " stop preview times(ms): "
162                         + Arrays.toString(stopPreviewTimes)
163                         + ". Average(ms): " + Stat.getAverage(stopPreviewTimes)
164                         + ". Min(ms): " + Stat.getMin(stopPreviewTimes)
165                         + ". Max(ms): " + Stat.getMax(stopPreviewTimes));
166                 Log.v(TAG, "Camera " + id + " device close times(ms): "
167                         + Arrays.toString(cameraCloseTimes)
168                         + ". Average(ms): " + Stat.getAverage(cameraCloseTimes)
169                         + ". Min(ms): " + Stat.getMin(cameraCloseTimes)
170                         + ". Max(ms): " + Stat.getMax(cameraCloseTimes));
171                 Log.v(TAG, "Camera " + id + " camera takepicture times(ms): "
172                         + Arrays.toString(cameraTakePictureTimes)
173                         + ". Average(ms): " + Stat.getAverage(cameraTakePictureTimes)
174                         + ". Min(ms): " + Stat.getMin(cameraTakePictureTimes)
175                         + ". Max(ms): " + Stat.getMax(cameraTakePictureTimes));
176             }
177 
178             avgCameraTakePictureTimes[count++] = Stat.getAverage(cameraTakePictureTimes);
179             reportLog.addValues("camera_open_time", cameraOpenTimes, ResultType.LOWER_BETTER,
180                     ResultUnit.MS);
181             reportLog.addValues("camera_start_preview_time", startPreviewTimes,
182                     ResultType.LOWER_BETTER, ResultUnit.MS);
183             if (afSupported) {
184                 reportLog.addValues("camera_autofocus_time", cameraAutoFocusTimes,
185                         ResultType.LOWER_BETTER, ResultUnit.MS);
186             }
187             reportLog.addValues("camera_stop_preview", stopPreviewTimes,
188                     ResultType.LOWER_BETTER, ResultUnit.MS);
189             reportLog.addValues("camera_close_time", cameraCloseTimes,
190                     ResultType.LOWER_BETTER, ResultUnit.MS);
191             reportLog.addValues("camera_takepicture_time", cameraTakePictureTimes,
192                     ResultType.LOWER_BETTER, ResultUnit.MS);
193 
194             reportLog.submit(mInstrumentation);
195         }
196 
197         if (mCameraIds.length != 0) {
198             DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
199                     "test_camera_takepicture_average");
200             reportLog.setSummary("camera_takepicture_average_time_for_all_cameras",
201                     Stat.getAverage(avgCameraTakePictureTimes), ResultType.LOWER_BETTER,
202                     ResultUnit.MS);
203             reportLog.submit(mInstrumentation);
204         }
205     }
206 }
207