# Copyright 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import math import os.path import time import its.caps import its.device import matplotlib from matplotlib import pylab import numpy as np NAME = os.path.basename(__file__).split(".")[0] # if the var(x) > var(stable) * this threshold, then device is considered vibrated # Test results shows the variance difference is larger for higher sampling frequency # This threshold is good enough for 50hz samples. THRESHOLD_VIBRATION_VAR = 10.0 # Match CameraDevice.java constant AUDIO_RESTRICTION_NONE = 0 AUDIO_RESTRICTION_VIBRATION = 1 AUDIO_RESTRICTION_VIBRATION_SOUND = 2 # The sleep time between vibrator on/off to avoid getting some residual vibrations SLEEP_BETWEEN_SAMPLES_SEC = 0.5 # The sleep time to collect sensor samples SLEEP_COLLECT_SAMPLES_SEC = 1.0 def calc_magnitude(e): x = e["x"] y = e["y"] z = e["z"] return math.sqrt(x*x + y*y + z*z) def main(): """Test vibrations can be muted by the camera audio restriction API.""" with its.device.ItsSession() as cam: props = cam.get_camera_properties() props = cam.override_with_hidden_physical_camera_props(props) sensors = cam.get_sensors() its.caps.skip_unless(sensors.get("accel") and sensors.get("vibrator")) cam.start_sensor_events() pattern_ms = [0, 1000] cam.do_vibrate(pattern_ms) test_length_second = sum(pattern_ms) / 1000 time.sleep(test_length_second) events = cam.get_sensor_events() print "Accelerometer events over %ds: %d " % (test_length_second, len(events["accel"])) times_ms = [e["time"]/float(1e6) for e in events["accel"]] t0 = times_ms[0] times_ms = [t - t0 for t in times_ms] magnitudes = [calc_magnitude(e) for e in events["accel"]] var_w_vibration = np.var(magnitudes) time.sleep(SLEEP_BETWEEN_SAMPLES_SEC) cam.start_sensor_events() time.sleep(SLEEP_COLLECT_SAMPLES_SEC) events = cam.get_sensor_events() magnitudes = [calc_magnitude(e) for e in events["accel"]] var_wo_vibration = np.var(magnitudes) if var_w_vibration < var_wo_vibration * THRESHOLD_VIBRATION_VAR: print "Warning: unable to detect vibration, variance w/wo vibration too close:"\ " %f/%f. Make sure device is on non-dampening surface" % ( var_w_vibration, var_wo_vibration) time.sleep(SLEEP_BETWEEN_SAMPLES_SEC) cam.start_sensor_events() cam.set_audio_restriction(AUDIO_RESTRICTION_VIBRATION) cam.do_vibrate(pattern_ms) time.sleep(SLEEP_COLLECT_SAMPLES_SEC) events = cam.get_sensor_events() magnitudes = [calc_magnitude(e) for e in events["accel"]] var_w_vibration_restricted = np.var(magnitudes) print "Accel variance with/without/restricted vibration (%f, %f, %f)" % ( var_w_vibration, var_wo_vibration, var_w_vibration_restricted) e_msg = "Device vibrated while vibration is muted" assert var_w_vibration_restricted < var_wo_vibration * THRESHOLD_VIBRATION_VAR, e_msg if __name__ == "__main__": main()