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