xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/tests/ZoomRatioTest.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2019 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 #define LOG_NDEBUG 0
18 #define LOG_TAG "ZoomRatioMapperTest"
19 
20 #include <gtest/gtest.h>
21 #include <utils/Errors.h>
22 
23 #include "../device3/ZoomRatioMapper.h"
24 
25 using namespace std;
26 using namespace android;
27 using namespace android::camera3;
28 
29 constexpr int kMaxAllowedPixelError = 1;
30 constexpr float kMaxAllowedRatioError = 0.1;
31 
32 constexpr int32_t testActiveArraySize[] = {100, 100, 1024, 768};
33 constexpr int32_t testPreCorrActiveArraySize[] = {90, 90, 1044, 788};
34 
35 constexpr int32_t testDefaultCropSize[][4] = {
36       {0, 0, 1024, 768},   // active array default crop
37       {0, 0, 1044, 788},   // preCorrection active array default crop
38 };
39 
40 constexpr int32_t test2xCropRegion[][4] = {
41       {256, 192, 512, 384}, // active array 2x zoom crop
42       {261, 197, 522, 394}, // preCorrection active array default crop
43 };
44 
45 constexpr int32_t testLetterBoxSize[][4] = {
46       {0, 96, 1024, 576}, // active array 2x zoom crop
47       {0, 106, 1024, 576}, // preCorrection active array default crop
48 };
49 
setupTestMapper(ZoomRatioMapper * m,float maxDigitalZoom,const int32_t activeArray[4],const int32_t preCorrectArray[4],bool hasZoomRatioRange,float zoomRatioRange[2],bool usePreCorrectArray)50 status_t setupTestMapper(ZoomRatioMapper *m, float maxDigitalZoom,
51         const int32_t activeArray[4], const int32_t preCorrectArray[4],
52         bool hasZoomRatioRange, float zoomRatioRange[2],
53         bool usePreCorrectArray) {
54     CameraMetadata deviceInfo;
55 
56     deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArray, 4);
57     deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, preCorrectArray, 4);
58     deviceInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxDigitalZoom, 1);
59     if (hasZoomRatioRange) {
60         deviceInfo.update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, zoomRatioRange, 2);
61     }
62 
63     bool supportNativeZoomRatio;
64     status_t res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
65     if (res != OK) {
66         return res;
67     }
68 
69     *m = ZoomRatioMapper(&deviceInfo, hasZoomRatioRange, usePreCorrectArray);
70     return OK;
71 }
72 
TEST(ZoomRatioTest,Initialization)73 TEST(ZoomRatioTest, Initialization) {
74     CameraMetadata deviceInfo;
75     status_t res;
76     camera_metadata_entry_t entry;
77 
78     deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
79             testPreCorrActiveArraySize, 4);
80     deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, testActiveArraySize, 4);
81 
82     // Test initialization from devices not supporting zoomRange
83     float maxDigitalZoom = 4.0f;
84     ZoomRatioMapper mapperNoZoomRange;
85     deviceInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxDigitalZoom, 1);
86     bool supportNativeZoomRatio;
87     res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
88     ASSERT_EQ(res, OK);
89     ASSERT_EQ(supportNativeZoomRatio, false);
90     mapperNoZoomRange = ZoomRatioMapper(&deviceInfo,
91             supportNativeZoomRatio, true/*usePreCorrectArray*/);
92     ASSERT_TRUE(mapperNoZoomRange.isValid());
93     mapperNoZoomRange = ZoomRatioMapper(&deviceInfo,
94             supportNativeZoomRatio, false/*usePreCorrectArray*/);
95     ASSERT_TRUE(mapperNoZoomRange.isValid());
96 
97     entry = deviceInfo.find(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
98     ASSERT_EQ(entry.count, 2U);
99     ASSERT_EQ(entry.data.f[0], 1.0);
100     ASSERT_EQ(entry.data.f[1], maxDigitalZoom);
101 
102     entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
103     ASSERT_GT(entry.count, 0U);
104     ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
105             ANDROID_CONTROL_ZOOM_RATIO_RANGE), entry.data.i32 + entry.count);
106 
107     entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
108     ASSERT_GT(entry.count, 0U);
109     ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
110             ANDROID_CONTROL_ZOOM_RATIO), entry.data.i32 + entry.count);
111 
112     entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
113     ASSERT_GT(entry.count, 0U);
114     ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
115             ANDROID_CONTROL_ZOOM_RATIO), entry.data.i32 + entry.count);
116 
117     // Test initialization from devices supporting zoomRange
118     float ratioRange[2] = {0.2f, maxDigitalZoom};
119     deviceInfo.update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, ratioRange, 2);
120     res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
121     ASSERT_EQ(res, OK);
122     ASSERT_EQ(supportNativeZoomRatio, true);
123     ZoomRatioMapper mapperWithZoomRange;
124     mapperWithZoomRange = ZoomRatioMapper(&deviceInfo,
125             supportNativeZoomRatio, true/*usePreCorrectArray*/);
126     ASSERT_TRUE(mapperWithZoomRange.isValid());
127     mapperWithZoomRange = ZoomRatioMapper(&deviceInfo,
128             supportNativeZoomRatio, false/*usePreCorrectArray*/);
129     ASSERT_TRUE(mapperWithZoomRange.isValid());
130 
131     entry = deviceInfo.find(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
132     ASSERT_EQ(entry.count, 2U);
133     ASSERT_EQ(entry.data.f[0], ratioRange[0]);
134     ASSERT_EQ(entry.data.f[1], ratioRange[1]);
135 
136     // Test default zoom ratio in template
137     CameraMetadata requestTemplate;
138     res = ZoomRatioMapper::initZoomRatioInTemplate(&requestTemplate);
139     ASSERT_EQ(res, OK);
140     entry = requestTemplate.find(ANDROID_CONTROL_ZOOM_RATIO);
141     ASSERT_EQ(entry.count, 1U);
142     ASSERT_EQ(entry.data.f[0], 1.0f);
143 
144     float customRatio = 0.5f;
145     res = requestTemplate.update(ANDROID_CONTROL_ZOOM_RATIO, &customRatio, 1);
146     ASSERT_EQ(res, OK);
147     res = ZoomRatioMapper::initZoomRatioInTemplate(&requestTemplate);
148     ASSERT_EQ(res, OK);
149     entry = requestTemplate.find(ANDROID_CONTROL_ZOOM_RATIO);
150     ASSERT_EQ(entry.count, 1U);
151     ASSERT_EQ(entry.data.f[0], customRatio);
152 }
153 
subScaleCoordinatesTest(bool usePreCorrectArray)154 void subScaleCoordinatesTest(bool usePreCorrectArray) {
155     ZoomRatioMapper mapper;
156     float maxDigitalZoom = 4.0f;
157     float zoomRatioRange[2];
158     ASSERT_EQ(OK, setupTestMapper(&mapper, maxDigitalZoom,
159             testActiveArraySize, testPreCorrActiveArraySize,
160             false/*hasZoomRatioRange*/, zoomRatioRange,
161             usePreCorrectArray));
162 
163     int32_t width = testActiveArraySize[2];
164     int32_t height = testActiveArraySize[3];
165     if (usePreCorrectArray) {
166         width = testPreCorrActiveArraySize[2];
167         height = testPreCorrActiveArraySize[3];
168     }
169 
170     std::array<int32_t, 16> originalCoords = {
171             0, 0, // top-left
172             width - 1, 0, // top-right
173             0, height - 1, // bottom-left
174             width - 1, height - 1, // bottom-right
175             (width - 1) / 2, (height - 1) / 2, // center
176             (width - 1) / 4, (height - 1) / 4, // top-left after 2x
177             (width - 1) / 3, (height - 1) * 2 / 3, // bottom-left after 3x zoom
178             (width - 1) * 7 / 8, (height - 1) / 2, // middle-right after 1.33x zoom
179     };
180 
181     // Verify 1.0x zoom doesn't change the coordinates
182     auto coords = originalCoords;
183     mapper.scaleCoordinates(coords.data(), coords.size()/2, 1.0f, false /*clamp*/, width, height);
184     for (size_t i = 0; i < coords.size(); i++) {
185         EXPECT_EQ(coords[i], originalCoords[i]);
186     }
187 
188     // Verify 2.0x zoom work as expected (no clamping)
189     std::array<float, 16> expected2xCoords = {
190             - (width - 1) / 2.0f, - (height - 1) / 2.0f,// top-left
191             (width - 1) * 3 / 2.0f, - (height - 1) / 2.0f, // top-right
192             - (width - 1) / 2.0f, (height - 1) * 3 / 2.0f, // bottom-left
193             (width - 1) * 3 / 2.0f, (height - 1) * 3 / 2.0f, // bottom-right
194             (width - 1) / 2.0f, (height - 1) / 2.0f, // center
195             0, 0, // top-left after 2x
196             (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f, // bottom-left after 3x zoom
197             (width - 1) * 5.0f / 4.0f, (height - 1) / 2.0f, // middle-right after 1.33x zoom
198     };
199     coords = originalCoords;
200     mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, false /*clamp*/, width, height);
201     for (size_t i = 0; i < coords.size(); i++) {
202         EXPECT_LE(std::abs(coords[i] - expected2xCoords[i]), kMaxAllowedPixelError);
203     }
204 
205     // Verify 2.0x zoom work as expected (with inclusive clamping)
206     std::array<float, 16> expected2xCoordsClampedInc = {
207             0, 0, // top-left
208             width - 1.0f, 0, // top-right
209             0, height - 1.0f, // bottom-left
210             width - 1.0f, height - 1.0f, // bottom-right
211             (width - 1) / 2.0f, (height - 1) / 2.0f, // center
212             0, 0, // top-left after 2x
213             (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f , // bottom-left after 3x zoom
214             width - 1.0f,  (height - 1) / 2.0f, // middle-right after 1.33x zoom
215     };
216     coords = originalCoords;
217     mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, true /*clamp*/, width, height);
218     for (size_t i = 0; i < coords.size(); i++) {
219         EXPECT_LE(std::abs(coords[i] - expected2xCoordsClampedInc[i]), kMaxAllowedPixelError);
220     }
221 
222     // Verify 2.0x zoom work as expected (with exclusive clamping)
223     std::array<float, 16> expected2xCoordsClampedExc = {
224             0, 0, // top-left
225             width - 1.0f, 0, // top-right
226             0, height - 1.0f, // bottom-left
227             width - 1.0f, height - 1.0f, // bottom-right
228             width / 2.0f, height / 2.0f, // center
229             0, 0, // top-left after 2x
230             (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f , // bottom-left after 3x zoom
231             width - 1.0f,  height / 2.0f, // middle-right after 1.33x zoom
232     };
233     coords = originalCoords;
234     mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, true /*clamp*/, width, height);
235     for (size_t i = 0; i < coords.size(); i++) {
236         EXPECT_LE(std::abs(coords[i] - expected2xCoordsClampedExc[i]), kMaxAllowedPixelError);
237     }
238 
239     // Verify 0.33x zoom work as expected
240     std::array<float, 16> expectedZoomOutCoords = {
241             (width - 1) / 3.0f, (height - 1) / 3.0f, // top-left
242             (width - 1) * 2 / 3.0f, (height - 1) / 3.0f, // top-right
243             (width - 1) / 3.0f, (height - 1) * 2 / 3.0f, // bottom-left
244             (width - 1) * 2 / 3.0f, (height - 1) * 2 / 3.0f, // bottom-right
245             (width - 1) / 2.0f, (height - 1) / 2.0f, // center
246             (width - 1) * 5 / 12.0f, (height - 1) * 5 / 12.0f, // top-left after 2x
247             (width - 1) * 4 / 9.0f, (height - 1) * 5 / 9.0f, // bottom-left after 3x zoom-in
248             (width - 1) * 5 / 8.0f, (height - 1) / 2.0f, // middle-right after 1.33x zoom-in
249     };
250     coords = originalCoords;
251     mapper.scaleCoordinates(coords.data(), coords.size()/2, 1.0f/3, false /*clamp*/, width, height);
252     for (size_t i = 0; i < coords.size(); i++) {
253         EXPECT_LE(std::abs(coords[i] - expectedZoomOutCoords[i]), kMaxAllowedPixelError);
254     }
255 
256     // Verify region zoom scaling doesn't generate invalid metering region
257     // (width < 0, or height < 0)
258     std::array<float, 3> scaleRatios = {10.0f, 1.0f, 0.1f};
259     for (float scaleRatio : scaleRatios) {
260         for (size_t i = 0; i < originalCoords.size(); i+= 2) {
261             int32_t coordinates[] = {originalCoords[i], originalCoords[i+1],
262                     originalCoords[i], originalCoords[i+1]};
263             mapper.scaleRegion(coordinates, scaleRatio, width, height);
264             EXPECT_LE(coordinates[0], coordinates[2]);
265             EXPECT_LE(coordinates[1], coordinates[3]);
266         }
267     }
268 }
269 
TEST(ZoomRatioTest,scaleCoordinatesTest)270 TEST(ZoomRatioTest, scaleCoordinatesTest) {
271     subScaleCoordinatesTest(false/*usePreCorrectArray*/);
272     subScaleCoordinatesTest(true/*usePreCorrectArray*/);
273 }
274 
subCropOverMaxDigitalZoomTest(bool usePreCorrectArray)275 void subCropOverMaxDigitalZoomTest(bool usePreCorrectArray) {
276     status_t res;
277     ZoomRatioMapper mapper;
278     float noZoomRatioRange[2];
279     res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
280             testActiveArraySize, testPreCorrActiveArraySize,
281             false/*hasZoomRatioRange*/, noZoomRatioRange,
282             usePreCorrectArray);
283     ASSERT_EQ(res, OK);
284 
285     CameraMetadata metadata;
286     camera_metadata_entry_t entry;
287 
288     size_t index = usePreCorrectArray ? 1 : 0;
289     metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
290     res = mapper.updateCaptureRequest(&metadata);
291     ASSERT_EQ(res, OK);
292     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
293     ASSERT_EQ(entry.count, 4U);
294     for (int i = 0; i < 4; i ++) {
295         EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
296     }
297 
298     metadata.update(ANDROID_SCALER_CROP_REGION, test2xCropRegion[index], 4);
299     res = mapper.updateCaptureResult(&metadata, false /*zoomMethodIsRatio*/,
300                                      true/*requestedZoomRatioIs1*/);
301     ASSERT_EQ(res, OK);
302     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
303     ASSERT_EQ(entry.count, 4U);
304     for (int i = 0; i < 4; i ++) {
305         EXPECT_EQ(entry.data.i32[i], test2xCropRegion[index][i]);
306     }
307     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
308     ASSERT_TRUE(entry.count == 0 || (entry.count == 1 && entry.data.f[0] == 1.0f));
309 }
310 
TEST(ZoomRatioTest,CropOverMaxDigitalZoomTest)311 TEST(ZoomRatioTest, CropOverMaxDigitalZoomTest) {
312     subCropOverMaxDigitalZoomTest(false/*usePreCorrectArray*/);
313     subCropOverMaxDigitalZoomTest(true/*usePreCorrectArray*/);
314 }
315 
subCropOverZoomRangeTest(bool usePreCorrectArray)316 void subCropOverZoomRangeTest(bool usePreCorrectArray) {
317     status_t res;
318     ZoomRatioMapper mapper;
319     float zoomRatioRange[2] = {0.5f, 4.0f};
320     res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
321             testActiveArraySize, testPreCorrActiveArraySize,
322             true/*hasZoomRatioRange*/, zoomRatioRange,
323             usePreCorrectArray);
324     ASSERT_EQ(res, OK);
325 
326     CameraMetadata metadata;
327     camera_metadata_entry_t entry;
328 
329     size_t index = usePreCorrectArray ? 1 : 0;
330 
331     // 2x zoom crop region, zoomRatio is 1.0f
332     metadata.update(ANDROID_SCALER_CROP_REGION, test2xCropRegion[index], 4);
333     res = mapper.updateCaptureRequest(&metadata);
334     ASSERT_EQ(res, OK);
335     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
336     ASSERT_EQ(entry.count, 4U);
337     for (int i = 0; i < 4; i++) {
338         EXPECT_LE(std::abs(entry.data.i32[i] - testDefaultCropSize[index][i]),
339                 kMaxAllowedPixelError);
340     }
341     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
342     EXPECT_NEAR(entry.data.f[0], 2.0f, kMaxAllowedRatioError);
343 
344     res = mapper.updateCaptureResult(&metadata, false/*useZoomMethod*/,
345                                      true/*requestedZoomRatioIs1*/);
346     ASSERT_EQ(res, OK);
347     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
348     EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
349     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
350     ASSERT_EQ(entry.count, 4U);
351     for (int i = 0; i < 4; i++) {
352         EXPECT_LE(std::abs(entry.data.i32[i] - test2xCropRegion[index][i]), kMaxAllowedPixelError);
353     }
354 
355     // Letter boxing crop region, zoomRatio is 1.0
356     float zoomRatio = 1.0f;
357     metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
358     metadata.update(ANDROID_SCALER_CROP_REGION, testLetterBoxSize[index], 4);
359     res = mapper.updateCaptureRequest(&metadata);
360     ASSERT_EQ(res, OK);
361     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
362     ASSERT_EQ(entry.count, 4U);
363     for (int i = 0; i < 4; i++) {
364         EXPECT_EQ(entry.data.i32[i], testLetterBoxSize[index][i]);
365     }
366     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
367     EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
368 
369     res = mapper.updateCaptureResult(&metadata, false/*zoomMethodIsRatio*/,
370                                      true/*requestedZoomRatioIs1*/);
371     ASSERT_EQ(res, OK);
372     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
373     ASSERT_EQ(entry.count, 4U);
374     for (int i = 0; i < 4; i++) {
375         EXPECT_EQ(entry.data.i32[i], testLetterBoxSize[index][i]);
376     }
377     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
378     EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
379 }
380 
TEST(ZoomRatioTest,CropOverZoomRangeTest)381 TEST(ZoomRatioTest, CropOverZoomRangeTest) {
382     subCropOverZoomRangeTest(false/*usePreCorrectArray*/);
383     subCropOverZoomRangeTest(true/*usePreCorrectArray*/);
384 }
385 
subZoomOverMaxDigitalZoomTest(bool usePreCorrectArray)386 void subZoomOverMaxDigitalZoomTest(bool usePreCorrectArray) {
387     status_t res;
388     ZoomRatioMapper mapper;
389     float noZoomRatioRange[2];
390     res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
391             testActiveArraySize, testPreCorrActiveArraySize,
392             false/*hasZoomRatioRange*/, noZoomRatioRange,
393             usePreCorrectArray);
394     ASSERT_EQ(res, OK);
395 
396     CameraMetadata metadata;
397     float zoomRatio = 3.0f;
398     camera_metadata_entry_t entry;
399 
400     size_t index = usePreCorrectArray ? 1 : 0;
401 
402     // Full active array crop, zoomRatio is 3.0f
403     metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
404     metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
405     res = mapper.updateCaptureRequest(&metadata);
406     ASSERT_EQ(res, OK);
407     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
408     ASSERT_EQ(entry.count, 4U);
409     std::array<float, 4> expectedCrop = {
410         testDefaultCropSize[index][2] / 3.0f, /*x*/
411         testDefaultCropSize[index][3] / 3.0f, /*y*/
412         testDefaultCropSize[index][2] / 3.0f, /*width*/
413         testDefaultCropSize[index][3] / 3.0f, /*height*/
414     };
415     for (int i = 0; i < 4; i++) {
416         EXPECT_LE(std::abs(entry.data.i32[i] - expectedCrop[i]), kMaxAllowedPixelError);
417     }
418 
419     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
420     if (entry.count == 1) {
421         EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
422     }
423 }
424 
TEST(ZoomRatioTest,ZoomOverMaxDigitalZoomTest)425 TEST(ZoomRatioTest, ZoomOverMaxDigitalZoomTest) {
426     subZoomOverMaxDigitalZoomTest(false/*usePreCorrectArray*/);
427     subZoomOverMaxDigitalZoomTest(true/*usePreCorrectArray*/);
428 }
429 
subZoomOverZoomRangeTest(bool usePreCorrectArray)430 void subZoomOverZoomRangeTest(bool usePreCorrectArray) {
431     status_t res;
432     ZoomRatioMapper mapper;
433     float zoomRatioRange[2] = {1.0f, 4.0f};
434     res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
435             testActiveArraySize, testPreCorrActiveArraySize,
436             true/*hasZoomRatioRange*/, zoomRatioRange,
437             usePreCorrectArray);
438     ASSERT_EQ(res, OK);
439 
440     CameraMetadata metadata;
441     float zoomRatio = 3.0f;
442     camera_metadata_entry_t entry;
443     size_t index = usePreCorrectArray ? 1 : 0;
444 
445     // Full active array crop, zoomRatio is 3.0f
446     metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
447     metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
448     res = mapper.updateCaptureRequest(&metadata);
449     ASSERT_EQ(res, OK);
450     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
451     ASSERT_EQ(entry.count, 4U);
452     for (int i = 0; i < 4; i ++) {
453         EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
454     }
455     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
456     ASSERT_EQ(entry.data.f[0], zoomRatio);
457 
458     res = mapper.updateCaptureResult(&metadata, false/*zoomMethodIsRatio*/,
459                                      false/*requestedZoomRatioIs1*/);
460     ASSERT_EQ(res, OK);
461     entry = metadata.find(ANDROID_SCALER_CROP_REGION);
462     ASSERT_EQ(entry.count, 4U);
463     for (int i = 0; i < 4; i ++) {
464         EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
465     }
466     entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
467     ASSERT_EQ(entry.data.f[0], zoomRatio);
468 }
469 
TEST(ZoomRatioTest,ZoomOverZoomRangeTest)470 TEST(ZoomRatioTest, ZoomOverZoomRangeTest) {
471     subZoomOverZoomRangeTest(false/*usePreCorrectArray*/);
472     subZoomOverZoomRangeTest(true/*usePreCorrectArray*/);
473 }
474