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