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 y8(props):
195    """Returns whether a device supports Y8 output.
196
197    Args:
198        props: Camera properties object.
199
200    Returns:
201        Boolean.
202    """
203    return len(its.objects.get_available_output_sizes("y8", props)) > 0
204
205def post_raw_sensitivity_boost(props):
206    """Returns whether a device supports post RAW sensitivity boost..
207
208    Args:
209        props: Camera properties object.
210
211    Returns:
212        Boolean.
213    """
214    return props.has_key("android.control.postRawSensitivityBoostRange") and \
215            props["android.control.postRawSensitivityBoostRange"] != [100, 100]
216
217def sensor_fusion(props):
218    """Returns whether the camera and motion sensor timestamps for the device
219    are in the same time domain and can be compared directly.
220
221    Args:
222        props: Camera properties object.
223
224    Returns:
225        Boolean.
226    """
227    return props.has_key("android.sensor.info.timestampSource") and \
228           props["android.sensor.info.timestampSource"] == 1
229
230def read_3a(props):
231    """Return whether a device supports reading out the following 3A settings:
232        sensitivity
233        exposure time
234        awb gain
235        awb cct
236        focus distance
237
238    Args:
239        props: Camera properties object.
240
241    Returns:
242        Boolean.
243    """
244    # TODO: check available result keys explicitly
245    return manual_sensor(props) and manual_post_proc(props)
246
247def compute_target_exposure(props):
248    """Return whether a device supports target exposure computation in its.target module.
249
250    Args:
251        props: Camera properties object.
252
253    Returns:
254        Boolean.
255    """
256    return manual_sensor(props) and manual_post_proc(props)
257
258def freeform_crop(props):
259    """Returns whether a device supports freefrom cropping.
260
261    Args:
262        props: Camera properties object.
263
264    Return:
265        Boolean.
266    """
267    return props.has_key("android.scaler.croppingType") and \
268           props["android.scaler.croppingType"] == 1
269
270def flash(props):
271    """Returns whether a device supports flash control.
272
273    Args:
274        props: Camera properties object.
275
276    Return:
277        Boolean.
278    """
279    return props.has_key("android.flash.info.available") and \
280           props["android.flash.info.available"] == 1
281
282def per_frame_control(props):
283    """Returns whether a device supports per frame control
284
285    Args:
286        props: Camera properties object.
287
288    Return:
289        Boolean.
290    """
291    return props.has_key("android.sync.maxLatency") and \
292           props["android.sync.maxLatency"] == 0
293
294def ev_compensation(props):
295    """Returns whether a device supports ev compensation
296
297    Args:
298        props: Camera properties object.
299
300    Return:
301        Boolean.
302    """
303    return props.has_key("android.control.aeCompensationRange") and \
304           props["android.control.aeCompensationRange"] != [0, 0]
305
306def ae_lock(props):
307    """Returns whether a device supports AE lock
308
309    Args:
310        props: Camera properties object.
311
312    Return:
313        Boolean.
314    """
315    return props.has_key("android.control.aeLockAvailable") and \
316           props["android.control.aeLockAvailable"] == 1
317
318def awb_lock(props):
319    """Returns whether a device supports AWB lock
320
321    Args:
322        props: Camera properties object.
323
324    Return:
325        Boolean.
326    """
327    return props.has_key("android.control.awbLockAvailable") and \
328           props["android.control.awbLockAvailable"] == 1
329
330def lsc_map(props):
331    """Returns whether a device supports lens shading map output
332
333    Args:
334        props: Camera properties object.
335
336    Return:
337        Boolean.
338    """
339    return props.has_key(
340            "android.statistics.info.availableLensShadingMapModes") and \
341        1 in props["android.statistics.info.availableLensShadingMapModes"]
342
343def lsc_off(props):
344    """Returns whether a device supports disabling lens shading correction
345
346    Args:
347        props: Camera properties object.
348
349    Return:
350        Boolean.
351    """
352    return props.has_key(
353            "android.shading.availableModes") and \
354        0 in props["android.shading.availableModes"]
355
356def yuv_reprocess(props):
357    """Returns whether a device supports YUV reprocessing.
358
359    Args:
360        props: Camera properties object.
361
362    Returns:
363        Boolean.
364    """
365    return props.has_key("android.request.availableCapabilities") and \
366           7 in props["android.request.availableCapabilities"]
367
368def private_reprocess(props):
369    """Returns whether a device supports PRIVATE reprocessing.
370
371    Args:
372        props: Camera properties object.
373
374    Returns:
375        Boolean.
376    """
377    return props.has_key("android.request.availableCapabilities") and \
378           4 in props["android.request.availableCapabilities"]
379
380def noise_reduction_mode(props, mode):
381    """Returns whether a device supports the noise reduction mode.
382
383    Args:
384        props: Camera properties objects.
385        mode: Integer, indicating the noise reduction mode to check for
386              availability.
387
388    Returns:
389        Boolean.
390    """
391    return props.has_key(
392            "android.noiseReduction.availableNoiseReductionModes") and mode \
393            in props["android.noiseReduction.availableNoiseReductionModes"];
394
395def edge_mode(props, mode):
396    """Returns whether a device supports the edge mode.
397
398    Args:
399        props: Camera properties objects.
400        mode: Integer, indicating the edge mode to check for availability.
401
402    Returns:
403        Boolean.
404    """
405    return props.has_key(
406            "android.edge.availableEdgeModes") and mode \
407            in props["android.edge.availableEdgeModes"];
408
409
410def lens_calibrated(props):
411    """Returns whether lens position is calibrated or not.
412
413    android.lens.info.focusDistanceCalibration has 3 modes.
414    0: Uncalibrated
415    1: Approximate
416    2: Calibrated
417
418    Args:
419        props: Camera properties objects.
420
421    Returns:
422        Boolean.
423    """
424    return props.has_key("android.lens.info.focusDistanceCalibration") and \
425         props["android.lens.info.focusDistanceCalibration"] == 2
426
427
428def lens_approx_calibrated(props):
429    """Returns whether lens position is calibrated or not.
430
431    android.lens.info.focusDistanceCalibration has 3 modes.
432    0: Uncalibrated
433    1: Approximate
434    2: Calibrated
435
436    Args:
437        props: Camera properties objects.
438
439    Returns:
440        Boolean.
441    """
442    return props.has_key("android.lens.info.focusDistanceCalibration") and \
443        (props["android.lens.info.focusDistanceCalibration"] == 1 or
444         props["android.lens.info.focusDistanceCalibration"] == 2)
445
446
447def fixed_focus(props):
448    """Returns whether a device is fixed focus.
449
450    props[android.lens.info.minimumFocusDistance] == 0 is fixed focus
451
452    Args:
453        props: Camera properties objects.
454
455    Returns:
456        Boolean.
457    """
458    return props.has_key("android.lens.info.minimumFocusDistance") and \
459        props["android.lens.info.minimumFocusDistance"] == 0
460
461def logical_multi_camera(props):
462    """Returns whether a device is a logical multi-camera.
463
464    Args:
465        props: Camera properties object.
466
467    Return:
468        Boolean.
469    """
470    return props.has_key("android.request.availableCapabilities") and \
471           11 in props["android.request.availableCapabilities"]
472
473def logical_multi_camera_physical_ids(props):
474    """Returns a logical multi-camera's underlying physical cameras.
475
476    Args:
477        props: Camera properties object.
478
479    Return:
480        list of physical cameras backing the logical multi-camera.
481    """
482    physicalIdsList = []
483    if logical_multi_camera(props):
484        physicalIdsList = props['camera.characteristics.physicalCamIds'];
485    return physicalIdsList
486
487def mono_camera(props):
488    """Returns whether a device is monochromatic.
489
490    Args:
491        props: Camera properties object.
492
493    Return:
494        Boolean.
495    """
496    return props.has_key("android.request.availableCapabilities") and \
497           12 in props["android.request.availableCapabilities"]
498
499
500def face_detect(props):
501    """Returns whether a device has face detection mode.
502
503    props['android.statistics.info.availableFaceDetectModes'] != 0 is face det
504
505    Args:
506        props: Camera properties objects.
507
508    Returns:
509        Boolean.
510    """
511    return props.has_key("android.statistics.info.availableFaceDetectModes") and \
512        props["android.statistics.info.availableFaceDetectModes"] != [0]
513
514
515def debug_mode():
516    """Returns True/False for whether test is run in debug mode.
517
518    Returns:
519        Boolean.
520    """
521    for s in sys.argv[1:]:
522        if s[:6] == "debug=" and s[6:] == "True":
523            return True
524    return False
525
526
527def sync_latency(props):
528    """Returns sync latency in number of frames.
529
530    If undefined, 8 frames.
531
532    Returns:
533        integer number of frames
534    """
535    sync_latency = props['android.sync.maxLatency']
536    if sync_latency < 0:
537        sync_latency = 8
538    return sync_latency
539
540
541def backward_compatible(props):
542    """Returns whether a device supports BACKWARD_COMPATIBLE.
543
544    Args:
545        props: Camera properties object.
546
547    Returns:
548        Boolean.
549    """
550    return props.has_key("android.request.availableCapabilities") and \
551              0 in props["android.request.availableCapabilities"]
552
553
554class __UnitTest(unittest.TestCase):
555    """Run a suite of unit tests on this module.
556    """
557    # TODO: Add more unit tests.
558
559if __name__ == '__main__':
560    unittest.main()
561