1# Copyright 2019 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"""Test to see if vibrations can be muted by camera-audio-restriction API."""
15
16import logging
17import math
18import time
19
20from mobly import test_runner
21import numpy as np
22
23import its_base_test
24import camera_properties_utils
25import its_session_utils
26
27
28# if the var(x) > var(stable) * this threshold, then device is considered
29# vibrated.Test results shows the variance difference is larger for higher
30# sampling frequency.This threshold is good enough for 50hz samples.
31THRESHOLD_VIBRATION_VAR = 10.0
32
33# Match CameraDevice.java constant
34AUDIO_RESTRICTION_VIBRATION = 1
35
36# The sleep time between vibrator on/off to avoid getting some residual
37# vibrations
38SLEEP_BETWEEN_SAMPLES_SEC = 0.5
39# The sleep time to collect sensor samples
40SLEEP_COLLECT_SAMPLES_SEC = 1.0
41PATTERN_MS = [0, 1000]
42
43
44def calc_magnitude(e):
45  x = e['x']
46  y = e['y']
47  z = e['z']
48  return math.sqrt(x * x + y * y + z * z)
49
50
51class VibrationRestrictionTest(its_base_test.ItsBaseTest):
52  """Test vibrations can be muted by the camera audio restriction API."""
53
54  def test_vibration_restriction(self):
55    with its_session_utils.ItsSession(
56        device_id=self.dut.serial,
57        camera_id=self.camera_id,
58        hidden_physical_id=self.hidden_physical_id) as cam:
59      props = cam.get_camera_properties()
60      props = cam.override_with_hidden_physical_camera_props(props)
61      sensors = cam.get_sensors()
62
63      camera_properties_utils.skip_unless(
64          sensors.get('accel') and sensors.get('vibrator'))
65
66      cam.start_sensor_events()
67      cam.do_vibrate(PATTERN_MS)
68      test_length_second = sum(PATTERN_MS) / 1000
69      time.sleep(test_length_second)
70      events = cam.get_sensor_events()
71      logging.debug('Accelerometer events over %ds: %d ', test_length_second,
72                    len(events['accel']))
73      times_ms = [e['time'] / float(1e6) for e in events['accel']]
74      t0 = times_ms[0]
75      times_ms = [t - t0 for t in times_ms]
76      magnitudes = [calc_magnitude(e) for e in events['accel']]
77      var_w_vibration = np.var(magnitudes)
78
79      time.sleep(SLEEP_BETWEEN_SAMPLES_SEC)
80      cam.start_sensor_events()
81      time.sleep(SLEEP_COLLECT_SAMPLES_SEC)
82      events = cam.get_sensor_events()
83      magnitudes = [calc_magnitude(e) for e in events['accel']]
84      var_wo_vibration = np.var(magnitudes)
85
86      if var_w_vibration < var_wo_vibration * THRESHOLD_VIBRATION_VAR:
87        logging.debug(
88            'Warning: unable to detect vibration, variance w/wo'
89            'vibration too close: %f/%f. Make sure device is on'
90            'non-dampening surface', var_w_vibration, var_wo_vibration)
91
92      time.sleep(SLEEP_BETWEEN_SAMPLES_SEC)
93      cam.start_sensor_events()
94      cam.set_audio_restriction(AUDIO_RESTRICTION_VIBRATION)
95      cam.do_vibrate(PATTERN_MS)
96      time.sleep(SLEEP_COLLECT_SAMPLES_SEC)
97      events = cam.get_sensor_events()
98      magnitudes = [calc_magnitude(e) for e in events['accel']]
99      var_w_vibration_restricted = np.var(magnitudes)
100
101      logging.debug(
102          'Accel variance with/without/restricted vibration (%f, %f, %f)',
103          var_w_vibration, var_wo_vibration, var_w_vibration_restricted)
104
105      e_msg = 'Device vibrated while vibration is muted'
106      vibration_variance = var_w_vibration_restricted < (
107          var_wo_vibration * THRESHOLD_VIBRATION_VAR)
108      assert vibration_variance, e_msg
109
110
111if __name__ == '__main__':
112  test_runner.main()
113