1# Copyright 2014 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import sys
16import unittest
17
18import its.objects
19
20
21def skip_unless(cond):
22    """Skips the test if the condition is false.
23
24    If a test is skipped, then it is exited and returns the special code
25    of 101 to the calling shell, which can be used by an external test
26    harness to differentiate a skip from a pass or fail.
27
28    Args:
29        cond: Boolean, which must be true for the test to not skip.
30
31    Returns:
32        Nothing.
33    """
34    SKIP_RET_CODE = 101
35
36    if not cond:
37        print "Test skipped"
38        sys.exit(SKIP_RET_CODE)
39
40def full_or_better(props):
41    """Returns whether a device is a FULL or better camera2 device.
42
43    Args:
44        props: Camera properties object.
45
46    Returns:
47        Boolean.
48    """
49    return props.has_key("android.info.supportedHardwareLevel") and \
50            props["android.info.supportedHardwareLevel"] != 2 and \
51            props["android.info.supportedHardwareLevel"] >= 1
52
53def level3(props):
54    """Returns whether a device is a LEVEL3 capability camera2 device.
55
56    Args:
57        props: Camera properties object.
58
59    Returns:
60        Boolean.
61    """
62    return props.has_key("android.info.supportedHardwareLevel") and \
63           props["android.info.supportedHardwareLevel"] == 3
64
65def full(props):
66    """Returns whether a device is a FULL capability camera2 device.
67
68    Args:
69        props: Camera properties object.
70
71    Returns:
72        Boolean.
73    """
74    return props.has_key("android.info.supportedHardwareLevel") and \
75           props["android.info.supportedHardwareLevel"] == 1
76
77def limited(props):
78    """Returns whether a device is a LIMITED capability camera2 device.
79
80    Args:
81        props: Camera properties object.
82
83    Returns:
84        Boolean.
85    """
86    return props.has_key("android.info.supportedHardwareLevel") and \
87           props["android.info.supportedHardwareLevel"] == 0
88
89def legacy(props):
90    """Returns whether a device is a LEGACY capability camera2 device.
91
92    Args:
93        props: Camera properties object.
94
95    Returns:
96        Boolean.
97    """
98    return props.has_key("android.info.supportedHardwareLevel") and \
99           props["android.info.supportedHardwareLevel"] == 2
100
101def distortion_correction(props):
102    """Returns whether a device supports DISTORTION_CORRECTION
103    capabilities.
104
105    Args:
106        props: Camera properties object.
107
108    Returns:
109        Boolean.
110    """
111    return props.has_key("android.lens.distortion") and \
112           props["android.lens.distortion"] is not None
113
114def manual_sensor(props):
115    """Returns whether a device supports MANUAL_SENSOR capabilities.
116
117    Args:
118        props: Camera properties object.
119
120    Returns:
121        Boolean.
122    """
123    return    props.has_key("android.request.availableCapabilities") and \
124              1 in props["android.request.availableCapabilities"]
125
126def manual_post_proc(props):
127    """Returns whether a device supports MANUAL_POST_PROCESSING capabilities.
128
129    Args:
130        props: Camera properties object.
131
132    Returns:
133        Boolean.
134    """
135    return    props.has_key("android.request.availableCapabilities") and \
136              2 in props["android.request.availableCapabilities"]
137
138def raw(props):
139    """Returns whether a device supports RAW capabilities.
140
141    Args:
142        props: Camera properties object.
143
144    Returns:
145        Boolean.
146    """
147    return props.has_key("android.request.availableCapabilities") and \
148           3 in props["android.request.availableCapabilities"]
149
150def raw16(props):
151    """Returns whether a device supports RAW16 output.
152
153    Args:
154        props: Camera properties object.
155
156    Returns:
157        Boolean.
158    """
159    return len(its.objects.get_available_output_sizes("raw", props)) > 0
160
161def raw10(props):
162    """Returns whether a device supports RAW10 output.
163
164    Args:
165        props: Camera properties object.
166
167    Returns:
168        Boolean.
169    """
170    return len(its.objects.get_available_output_sizes("raw10", props)) > 0
171
172def raw12(props):
173    """Returns whether a device supports RAW12 output.
174
175    Args:
176        props: Camera properties object.
177
178    Returns:
179        Boolean.
180    """
181    return len(its.objects.get_available_output_sizes("raw12", props)) > 0
182
183def raw_output(props):
184    """Returns whether a device supports any of RAW output format.
185
186    Args:
187        props: Camera properties object.
188
189    Returns:
190        Boolean.
191    """
192    return raw16(props) or raw10(props) or raw12(props)
193
194def post_raw_sensitivity_boost(props):
195    """Returns whether a device supports post RAW sensitivity boost..
196
197    Args:
198        props: Camera properties object.
199
200    Returns:
201        Boolean.
202    """
203    return props.has_key("android.control.postRawSensitivityBoostRange") and \
204            props["android.control.postRawSensitivityBoostRange"] != [100, 100]
205
206def sensor_fusion(props):
207    """Returns whether the camera and motion sensor timestamps for the device
208    are in the same time domain and can be compared directly.
209
210    Args:
211        props: Camera properties object.
212
213    Returns:
214        Boolean.
215    """
216    return props.has_key("android.sensor.info.timestampSource") and \
217           props["android.sensor.info.timestampSource"] == 1
218
219def read_3a(props):
220    """Return whether a device supports reading out the following 3A settings:
221        sensitivity
222        exposure time
223        awb gain
224        awb cct
225        focus distance
226
227    Args:
228        props: Camera properties object.
229
230    Returns:
231        Boolean.
232    """
233    # TODO: check available result keys explicitly
234    return manual_sensor(props) and manual_post_proc(props)
235
236def compute_target_exposure(props):
237    """Return whether a device supports target exposure computation in its.target module.
238
239    Args:
240        props: Camera properties object.
241
242    Returns:
243        Boolean.
244    """
245    return manual_sensor(props) and manual_post_proc(props)
246
247def freeform_crop(props):
248    """Returns whether a device supports freefrom cropping.
249
250    Args:
251        props: Camera properties object.
252
253    Return:
254        Boolean.
255    """
256    return props.has_key("android.scaler.croppingType") and \
257           props["android.scaler.croppingType"] == 1
258
259def flash(props):
260    """Returns whether a device supports flash control.
261
262    Args:
263        props: Camera properties object.
264
265    Return:
266        Boolean.
267    """
268    return props.has_key("android.flash.info.available") and \
269           props["android.flash.info.available"] == 1
270
271def per_frame_control(props):
272    """Returns whether a device supports per frame control
273
274    Args:
275        props: Camera properties object.
276
277    Return:
278        Boolean.
279    """
280    return props.has_key("android.sync.maxLatency") and \
281           props["android.sync.maxLatency"] == 0
282
283def ev_compensation(props):
284    """Returns whether a device supports ev compensation
285
286    Args:
287        props: Camera properties object.
288
289    Return:
290        Boolean.
291    """
292    return props.has_key("android.control.aeCompensationRange") and \
293           props["android.control.aeCompensationRange"] != [0, 0]
294
295def ae_lock(props):
296    """Returns whether a device supports AE lock
297
298    Args:
299        props: Camera properties object.
300
301    Return:
302        Boolean.
303    """
304    return props.has_key("android.control.aeLockAvailable") and \
305           props["android.control.aeLockAvailable"] == 1
306
307def awb_lock(props):
308    """Returns whether a device supports AWB lock
309
310    Args:
311        props: Camera properties object.
312
313    Return:
314        Boolean.
315    """
316    return props.has_key("android.control.awbLockAvailable") and \
317           props["android.control.awbLockAvailable"] == 1
318
319def lsc_map(props):
320    """Returns whether a device supports lens shading map output
321
322    Args:
323        props: Camera properties object.
324
325    Return:
326        Boolean.
327    """
328    return props.has_key(
329            "android.statistics.info.availableLensShadingMapModes") and \
330        1 in props["android.statistics.info.availableLensShadingMapModes"]
331
332def lsc_off(props):
333    """Returns whether a device supports disabling lens shading correction
334
335    Args:
336        props: Camera properties object.
337
338    Return:
339        Boolean.
340    """
341    return props.has_key(
342            "android.shading.availableModes") and \
343        0 in props["android.shading.availableModes"]
344
345def yuv_reprocess(props):
346    """Returns whether a device supports YUV reprocessing.
347
348    Args:
349        props: Camera properties object.
350
351    Returns:
352        Boolean.
353    """
354    return props.has_key("android.request.availableCapabilities") and \
355           7 in props["android.request.availableCapabilities"]
356
357def private_reprocess(props):
358    """Returns whether a device supports PRIVATE reprocessing.
359
360    Args:
361        props: Camera properties object.
362
363    Returns:
364        Boolean.
365    """
366    return props.has_key("android.request.availableCapabilities") and \
367           4 in props["android.request.availableCapabilities"]
368
369def noise_reduction_mode(props, mode):
370    """Returns whether a device supports the noise reduction mode.
371
372    Args:
373        props: Camera properties objects.
374        mode: Integer, indicating the noise reduction mode to check for
375              availability.
376
377    Returns:
378        Boolean.
379    """
380    return props.has_key(
381            "android.noiseReduction.availableNoiseReductionModes") and mode \
382            in props["android.noiseReduction.availableNoiseReductionModes"];
383
384def edge_mode(props, mode):
385    """Returns whether a device supports the edge mode.
386
387    Args:
388        props: Camera properties objects.
389        mode: Integer, indicating the edge mode to check for availability.
390
391    Returns:
392        Boolean.
393    """
394    return props.has_key(
395            "android.edge.availableEdgeModes") and mode \
396            in props["android.edge.availableEdgeModes"];
397
398
399def lens_calibrated(props):
400    """Returns whether lens position is calibrated or not.
401
402    android.lens.info.focusDistanceCalibration has 3 modes.
403    0: Uncalibrated
404    1: Approximate
405    2: Calibrated
406
407    Args:
408        props: Camera properties objects.
409
410    Returns:
411        Boolean.
412    """
413    return props.has_key("android.lens.info.focusDistanceCalibration") and \
414         props["android.lens.info.focusDistanceCalibration"] == 2
415
416
417def lens_approx_calibrated(props):
418    """Returns whether lens position is calibrated or not.
419
420    android.lens.info.focusDistanceCalibration has 3 modes.
421    0: Uncalibrated
422    1: Approximate
423    2: Calibrated
424
425    Args:
426        props: Camera properties objects.
427
428    Returns:
429        Boolean.
430    """
431    return props.has_key("android.lens.info.focusDistanceCalibration") and \
432        (props["android.lens.info.focusDistanceCalibration"] == 1 or
433         props["android.lens.info.focusDistanceCalibration"] == 2)
434
435
436def fixed_focus(props):
437    """Returns whether a device is fixed focus.
438
439    props[android.lens.info.minimumFocusDistance] == 0 is fixed focus
440
441    Args:
442        props: Camera properties objects.
443
444    Returns:
445        Boolean.
446    """
447    return props.has_key("android.lens.info.minimumFocusDistance") and \
448        props["android.lens.info.minimumFocusDistance"] == 0
449
450def logical_multi_camera(props):
451    """Returns whether a device is a logical multi-camera.
452
453    Args:
454        props: Camera properties object.
455
456    Return:
457        Boolean.
458    """
459    return props.has_key("android.request.availableCapabilities") and \
460           11 in props["android.request.availableCapabilities"]
461
462def logical_multi_camera_physical_ids(props):
463    """Returns a logical multi-camera's underlying physical cameras.
464
465    Args:
466        props: Camera properties object.
467
468    Return:
469        list of physical cameras backing the logical multi-camera.
470    """
471    physicalIdsList = []
472    if logical_multi_camera(props):
473        physicalIdsList = props['camera.characteristics.physicalCamIds'];
474    return physicalIdsList
475
476def mono_camera(props):
477    """Returns whether a device is monochromatic.
478
479    Args:
480        props: Camera properties object.
481
482    Return:
483        Boolean.
484    """
485    return props.has_key("android.request.availableCapabilities") and \
486           12 in props["android.request.availableCapabilities"]
487
488
489def face_detect(props):
490    """Returns whether a device has face detection mode.
491
492    props['android.statistics.info.availableFaceDetectModes'] != 0 is face det
493
494    Args:
495        props: Camera properties objects.
496
497    Returns:
498        Boolean.
499    """
500    return props.has_key("android.statistics.info.availableFaceDetectModes") and \
501        props["android.statistics.info.availableFaceDetectModes"] != [0]
502
503
504def debug_mode():
505    """Returns True/False for whether test is run in debug mode.
506
507    Returns:
508        Boolean.
509    """
510    for s in sys.argv[1:]:
511        if s[:6] == "debug=" and s[6:] == "True":
512            return True
513    return False
514
515
516class __UnitTest(unittest.TestCase):
517    """Run a suite of unit tests on this module.
518    """
519    # TODO: Add more unit tests.
520
521if __name__ == '__main__':
522    unittest.main()
523