• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# lens facing
21FACING_FRONT = 0
22FACING_BACK = 1
23FACING_EXTERNAL = 2
24
25SKIP_RET_CODE = 101
26
27def skip_unless(cond):
28    """Skips the test if the condition is false.
29
30    If a test is skipped, then it is exited and returns the special code
31    of 101 to the calling shell, which can be used by an external test
32    harness to differentiate a skip from a pass or fail.
33
34    Args:
35        cond: Boolean, which must be true for the test to not skip.
36
37    Returns:
38        Nothing.
39    """
40    if not cond:
41        print "Test skipped"
42        sys.exit(SKIP_RET_CODE)
43
44def full_or_better(props):
45    """Returns whether a device is a FULL or better camera2 device.
46
47    Args:
48        props: Camera properties object.
49
50    Returns:
51        Boolean.
52    """
53    return props.has_key("android.info.supportedHardwareLevel") and \
54            props["android.info.supportedHardwareLevel"] != 2 and \
55            props["android.info.supportedHardwareLevel"] >= 1
56
57def level3(props):
58    """Returns whether a device is a LEVEL3 capability camera2 device.
59
60    Args:
61        props: Camera properties object.
62
63    Returns:
64        Boolean.
65    """
66    return props.has_key("android.info.supportedHardwareLevel") and \
67           props["android.info.supportedHardwareLevel"] == 3
68
69def full(props):
70    """Returns whether a device is a FULL capability camera2 device.
71
72    Args:
73        props: Camera properties object.
74
75    Returns:
76        Boolean.
77    """
78    return props.has_key("android.info.supportedHardwareLevel") and \
79           props["android.info.supportedHardwareLevel"] == 1
80
81def limited(props):
82    """Returns whether a device is a LIMITED capability camera2 device.
83
84    Args:
85        props: Camera properties object.
86
87    Returns:
88        Boolean.
89    """
90    return props.has_key("android.info.supportedHardwareLevel") and \
91           props["android.info.supportedHardwareLevel"] == 0
92
93def legacy(props):
94    """Returns whether a device is a LEGACY capability camera2 device.
95
96    Args:
97        props: Camera properties object.
98
99    Returns:
100        Boolean.
101    """
102    return props.has_key("android.info.supportedHardwareLevel") and \
103           props["android.info.supportedHardwareLevel"] == 2
104
105def distortion_correction(props):
106    """Returns whether a device supports DISTORTION_CORRECTION
107    capabilities.
108
109    Args:
110        props: Camera properties object.
111
112    Returns:
113        Boolean.
114    """
115    return props.has_key("android.lens.distortion") and \
116           props["android.lens.distortion"] is not None
117
118def manual_sensor(props):
119    """Returns whether a device supports MANUAL_SENSOR capabilities.
120
121    Args:
122        props: Camera properties object.
123
124    Returns:
125        Boolean.
126    """
127    return    props.has_key("android.request.availableCapabilities") and \
128              1 in props["android.request.availableCapabilities"]
129
130def manual_post_proc(props):
131    """Returns whether a device supports MANUAL_POST_PROCESSING capabilities.
132
133    Args:
134        props: Camera properties object.
135
136    Returns:
137        Boolean.
138    """
139    return    props.has_key("android.request.availableCapabilities") and \
140              2 in props["android.request.availableCapabilities"]
141
142def raw(props):
143    """Returns whether a device supports RAW capabilities.
144
145    Args:
146        props: Camera properties object.
147
148    Returns:
149        Boolean.
150    """
151    return props.has_key("android.request.availableCapabilities") and \
152           3 in props["android.request.availableCapabilities"]
153
154def raw16(props):
155    """Returns whether a device supports RAW16 output.
156
157    Args:
158        props: Camera properties object.
159
160    Returns:
161        Boolean.
162    """
163    return len(its.objects.get_available_output_sizes("raw", props)) > 0
164
165def raw10(props):
166    """Returns whether a device supports RAW10 output.
167
168    Args:
169        props: Camera properties object.
170
171    Returns:
172        Boolean.
173    """
174    return len(its.objects.get_available_output_sizes("raw10", props)) > 0
175
176def raw12(props):
177    """Returns whether a device supports RAW12 output.
178
179    Args:
180        props: Camera properties object.
181
182    Returns:
183        Boolean.
184    """
185    return len(its.objects.get_available_output_sizes("raw12", props)) > 0
186
187def raw_output(props):
188    """Returns whether a device supports any of RAW output format.
189
190    Args:
191        props: Camera properties object.
192
193    Returns:
194        Boolean.
195    """
196    return raw16(props) or raw10(props) or raw12(props)
197
198def y8(props):
199    """Returns whether a device supports Y8 output.
200
201    Args:
202        props: Camera properties object.
203
204    Returns:
205        Boolean.
206    """
207    return len(its.objects.get_available_output_sizes("y8", props)) > 0
208
209def post_raw_sensitivity_boost(props):
210    """Returns whether a device supports post RAW sensitivity boost..
211
212    Args:
213        props: Camera properties object.
214
215    Returns:
216        Boolean.
217    """
218    return props.has_key("android.control.postRawSensitivityBoostRange") and \
219            props["android.control.postRawSensitivityBoostRange"] != [100, 100]
220
221def sensor_fusion(props):
222    """Returns whether the camera and motion sensor timestamps for the device
223    are in the same time domain and can be compared directly.
224
225    Args:
226        props: Camera properties object.
227
228    Returns:
229        Boolean.
230    """
231    return props.has_key("android.sensor.info.timestampSource") and \
232           props["android.sensor.info.timestampSource"] == 1
233
234def read_3a(props):
235    """Return whether a device supports reading out the following 3A settings:
236        sensitivity
237        exposure time
238        awb gain
239        awb cct
240        focus distance
241
242    Args:
243        props: Camera properties object.
244
245    Returns:
246        Boolean.
247    """
248    # TODO: check available result keys explicitly
249    return manual_sensor(props) and manual_post_proc(props)
250
251def compute_target_exposure(props):
252    """Return whether a device supports target exposure computation in its.target module.
253
254    Args:
255        props: Camera properties object.
256
257    Returns:
258        Boolean.
259    """
260    return manual_sensor(props) and manual_post_proc(props)
261
262def freeform_crop(props):
263    """Returns whether a device supports freefrom cropping.
264
265    Args:
266        props: Camera properties object.
267
268    Return:
269        Boolean.
270    """
271    return props.has_key("android.scaler.croppingType") and \
272           props["android.scaler.croppingType"] == 1
273
274def flash(props):
275    """Returns whether a device supports flash control.
276
277    Args:
278        props: Camera properties object.
279
280    Return:
281        Boolean.
282    """
283    return props.has_key("android.flash.info.available") and \
284           props["android.flash.info.available"] == 1
285
286def per_frame_control(props):
287    """Returns whether a device supports per frame control
288
289    Args:
290        props: Camera properties object.
291
292    Return:
293        Boolean.
294    """
295    return props.has_key("android.sync.maxLatency") and \
296           props["android.sync.maxLatency"] == 0
297
298def ev_compensation(props):
299    """Returns whether a device supports ev compensation
300
301    Args:
302        props: Camera properties object.
303
304    Return:
305        Boolean.
306    """
307    return props.has_key("android.control.aeCompensationRange") and \
308           props["android.control.aeCompensationRange"] != [0, 0]
309
310def ae_lock(props):
311    """Returns whether a device supports AE lock
312
313    Args:
314        props: Camera properties object.
315
316    Return:
317        Boolean.
318    """
319    return props.has_key("android.control.aeLockAvailable") and \
320           props["android.control.aeLockAvailable"] == 1
321
322def awb_lock(props):
323    """Returns whether a device supports AWB lock
324
325    Args:
326        props: Camera properties object.
327
328    Return:
329        Boolean.
330    """
331    return props.has_key("android.control.awbLockAvailable") and \
332           props["android.control.awbLockAvailable"] == 1
333
334def lsc_map(props):
335    """Returns whether a device supports lens shading map output
336
337    Args:
338        props: Camera properties object.
339
340    Return:
341        Boolean.
342    """
343    return props.has_key(
344            "android.statistics.info.availableLensShadingMapModes") and \
345        1 in props["android.statistics.info.availableLensShadingMapModes"]
346
347def lsc_off(props):
348    """Returns whether a device supports disabling lens shading correction
349
350    Args:
351        props: Camera properties object.
352
353    Return:
354        Boolean.
355    """
356    return props.has_key(
357            "android.shading.availableModes") and \
358        0 in props["android.shading.availableModes"]
359
360def yuv_reprocess(props):
361    """Returns whether a device supports YUV reprocessing.
362
363    Args:
364        props: Camera properties object.
365
366    Returns:
367        Boolean.
368    """
369    return props.has_key("android.request.availableCapabilities") and \
370           7 in props["android.request.availableCapabilities"]
371
372def private_reprocess(props):
373    """Returns whether a device supports PRIVATE reprocessing.
374
375    Args:
376        props: Camera properties object.
377
378    Returns:
379        Boolean.
380    """
381    return props.has_key("android.request.availableCapabilities") and \
382           4 in props["android.request.availableCapabilities"]
383
384def noise_reduction_mode(props, mode):
385    """Returns whether a device supports the noise reduction mode.
386
387    Args:
388        props: Camera properties objects.
389        mode: Integer, indicating the noise reduction mode to check for
390              availability.
391
392    Returns:
393        Boolean.
394    """
395    return props.has_key(
396            "android.noiseReduction.availableNoiseReductionModes") and mode \
397            in props["android.noiseReduction.availableNoiseReductionModes"];
398
399def edge_mode(props, mode):
400    """Returns whether a device supports the edge mode.
401
402    Args:
403        props: Camera properties objects.
404        mode: Integer, indicating the edge mode to check for availability.
405
406    Returns:
407        Boolean.
408    """
409    return props.has_key(
410            "android.edge.availableEdgeModes") and mode \
411            in props["android.edge.availableEdgeModes"];
412
413
414def lens_calibrated(props):
415    """Returns whether lens position is calibrated or not.
416
417    android.lens.info.focusDistanceCalibration has 3 modes.
418    0: Uncalibrated
419    1: Approximate
420    2: Calibrated
421
422    Args:
423        props: Camera properties objects.
424
425    Returns:
426        Boolean.
427    """
428    return props.has_key("android.lens.info.focusDistanceCalibration") and \
429         props["android.lens.info.focusDistanceCalibration"] == 2
430
431
432def lens_approx_calibrated(props):
433    """Returns whether lens position is calibrated or not.
434
435    android.lens.info.focusDistanceCalibration has 3 modes.
436    0: Uncalibrated
437    1: Approximate
438    2: Calibrated
439
440    Args:
441        props: Camera properties objects.
442
443    Returns:
444        Boolean.
445    """
446    return props.has_key("android.lens.info.focusDistanceCalibration") and \
447        (props["android.lens.info.focusDistanceCalibration"] == 1 or
448         props["android.lens.info.focusDistanceCalibration"] == 2)
449
450
451def fixed_focus(props):
452    """Returns whether a device is fixed focus.
453
454    props[android.lens.info.minimumFocusDistance] == 0 is fixed focus
455
456    Args:
457        props: Camera properties objects.
458
459    Returns:
460        Boolean.
461    """
462    return props.has_key("android.lens.info.minimumFocusDistance") and \
463        props["android.lens.info.minimumFocusDistance"] == 0
464
465def logical_multi_camera(props):
466    """Returns whether a device is a logical multi-camera.
467
468    Args:
469        props: Camera properties object.
470
471    Return:
472        Boolean.
473    """
474    return props.has_key("android.request.availableCapabilities") and \
475           11 in props["android.request.availableCapabilities"]
476
477def logical_multi_camera_physical_ids(props):
478    """Returns a logical multi-camera's underlying physical cameras.
479
480    Args:
481        props: Camera properties object.
482
483    Return:
484        list of physical cameras backing the logical multi-camera.
485    """
486    physicalIdsList = []
487    if logical_multi_camera(props):
488        physicalIdsList = props['camera.characteristics.physicalCamIds'];
489    return physicalIdsList
490
491def mono_camera(props):
492    """Returns whether a device is monochromatic.
493
494    Args:
495        props: Camera properties object.
496
497    Return:
498        Boolean.
499    """
500    return props.has_key("android.request.availableCapabilities") and \
501           12 in props["android.request.availableCapabilities"]
502
503
504def face_detect(props):
505    """Returns whether a device has face detection mode.
506
507    props['android.statistics.info.availableFaceDetectModes'] != 0 is face det
508
509    Args:
510        props: Camera properties objects.
511
512    Returns:
513        Boolean.
514    """
515    return props.has_key("android.statistics.info.availableFaceDetectModes") and \
516        props["android.statistics.info.availableFaceDetectModes"] != [0]
517
518
519def debug_mode():
520    """Returns True/False for whether test is run in debug mode.
521
522    Returns:
523        Boolean.
524    """
525    for s in sys.argv[1:]:
526        if s[:6] == "debug=" and s[6:] == "True":
527            return True
528    return False
529
530
531def sync_latency(props):
532    """Returns sync latency in number of frames.
533
534    If undefined, 8 frames.
535
536    Returns:
537        integer number of frames
538    """
539    sync_latency = props['android.sync.maxLatency']
540    if sync_latency < 0:
541        sync_latency = 8
542    return sync_latency
543
544
545def backward_compatible(props):
546    """Returns whether a device supports BACKWARD_COMPATIBLE.
547
548    Args:
549        props: Camera properties object.
550
551    Returns:
552        Boolean.
553    """
554    return props.has_key("android.request.availableCapabilities") and \
555              0 in props["android.request.availableCapabilities"]
556
557
558def sensor_fusion_test_capable(props, cam):
559    """Determine if test_sensor_fusion is run."""
560    return all([
561            its.caps.sensor_fusion(props),
562            its.caps.manual_sensor(props),
563            props["android.lens.facing"] != FACING_EXTERNAL,
564            cam.get_sensors().get("gyro")])
565
566
567def multi_camera_frame_sync_capable(props):
568    """Determine if test_multi_camera_frame_sync is run."""
569    return all([
570            read_3a(props),
571            per_frame_control(props),
572            logical_multi_camera(props),
573            sensor_fusion(props)])
574
575
576def continuous_picture(props):
577    """Returns whether a device supports CONTINUOUS_PICTURE."""
578    return props.has_key('android.control.afAvailableModes') and \
579              4 in props['android.control.afAvailableModes']
580
581
582def af_scene_change(props):
583    """Returns whether a device supports afSceneChange."""
584    return props.has_key('camera.characteristics.resultKeys') and \
585              'android.control.afSceneChange' in props['camera.characteristics.resultKeys']
586
587
588def zoom_ratio_range(props):
589    """Returns whether a device supports zoom capabilities.
590
591    Args:
592        props: Camera properties object.
593
594    Returns:
595        Boolean.
596    """
597    return props.has_key('android.control.zoomRatioRange') and \
598           props['android.control.zoomRatioRange'] is not None
599
600
601def jpeg_quality(props):
602    """Returns whether a device supports JPEG quality."""
603    return props.has_key('camera.characteristics.requestKeys') and \
604              'android.jpeg.quality' in props['camera.characteristics.requestKeys']
605
606
607class __UnitTest(unittest.TestCase):
608    """Run a suite of unit tests on this module.
609    """
610    # TODO: Add more unit tests.
611
612if __name__ == '__main__':
613    unittest.main()
614