1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.cts.verifier.sensors.helpers; 18 19 import com.android.cts.verifier.R; 20 import com.android.cts.verifier.sensors.base.ISensorTestStateContainer; 21 22 import android.content.ContentResolver; 23 import android.content.pm.PackageManager; 24 import android.os.Build; 25 import android.provider.Settings; 26 27 import java.lang.reflect.Field; 28 29 /** 30 * A helper class that provides a mechanism to: 31 * - prompt users to activate/deactivate features that are known to register for sensor data. 32 * - turn on/off certain components of the device on behalf of the test (described as 'runtime 33 * features') 34 * - keep track of the initial state for each sensor feature, so it can be restored at will 35 */ 36 public class SensorFeaturesDeactivator { 37 38 private final ISensorTestStateContainer mStateContainer; 39 40 private final SensorSettingContainer mAirplaneMode = new AirplaneModeSettingContainer(); 41 private final SensorSettingContainer mScreenBrightnessMode = 42 new ScreenBrightnessModeSettingContainer(); 43 private final SensorSettingContainer mAmbientDisplayMode = new AmbientDisplaySettingContainer(); 44 private final SensorSettingContainer mAutoRotateScreenMode = 45 new AutoRotateScreenModeSettingContainer(); 46 private final SensorSettingContainer mKeepScreenOnMode = new KeepScreenOnModeSettingContainer(); 47 private final SensorSettingContainer mLocationMode = new LocationModeSettingContainer(); 48 49 public SensorFeaturesDeactivator(ISensorTestStateContainer stateContainer) { 50 mStateContainer = stateContainer; 51 } 52 53 public synchronized void requestDeactivationOfFeatures() throws InterruptedException { 54 captureInitialState(); 55 56 mAirplaneMode.requestToSetMode(mStateContainer, true); 57 mScreenBrightnessMode.requestToSetMode(mStateContainer, false); 58 mAmbientDisplayMode.requestToSetMode(mStateContainer, false); 59 mAutoRotateScreenMode.requestToSetMode(mStateContainer, false); 60 mKeepScreenOnMode.requestToSetMode(mStateContainer, false); 61 mLocationMode.requestToSetMode(mStateContainer, false); 62 63 // TODO: find a way to find out if there are clients still registered at this time 64 mStateContainer.getTestLogger() 65 .logInstructions(R.string.snsr_sensor_feature_deactivation); 66 mStateContainer.waitForUserToContinue(); 67 } 68 69 public synchronized void requestToRestoreFeatures() throws InterruptedException { 70 if (Thread.currentThread().isInterrupted()) { 71 // TODO: in the future, if the thread is interrupted, we might need to serialize the 72 // intermediate state we acquired so we can restore when we have a chance 73 return; 74 } 75 76 mAirplaneMode.requestToResetMode(mStateContainer); 77 mScreenBrightnessMode.requestToResetMode(mStateContainer); 78 mAmbientDisplayMode.requestToResetMode(mStateContainer); 79 mAutoRotateScreenMode.requestToResetMode(mStateContainer); 80 mKeepScreenOnMode.requestToResetMode(mStateContainer); 81 mLocationMode.requestToResetMode(mStateContainer); 82 } 83 84 private void captureInitialState() { 85 mAirplaneMode.captureInitialState(); 86 mScreenBrightnessMode.captureInitialState(); 87 mAmbientDisplayMode.captureInitialState(); 88 mAutoRotateScreenMode.captureInitialState(); 89 mLocationMode.captureInitialState(); 90 mKeepScreenOnMode.captureInitialState(); 91 } 92 93 private class AirplaneModeSettingContainer extends SensorSettingContainer { 94 public AirplaneModeSettingContainer() { 95 super(Settings.ACTION_AIRPLANE_MODE_SETTINGS, R.string.snsr_setting_airplane_mode); 96 } 97 98 @Override 99 protected int getSettingMode(int defaultValue) { 100 ContentResolver contentResolver = mStateContainer.getContentResolver(); 101 // Settings.System.AIRPLANE_MODE_ON is deprecated in API 17 102 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 103 return Settings.System 104 .getInt(contentResolver, Settings.System.AIRPLANE_MODE_ON, defaultValue); 105 } else { 106 return Settings.Global 107 .getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, defaultValue); 108 } 109 } 110 111 @Override 112 protected boolean isSettingAvailable() { 113 // call base first, lean back UI device does not have airplane mode 114 return super.isSettingAvailable() && 115 !(mStateContainer.hasSystemFeature(PackageManager.FEATURE_LEANBACK)); 116 } 117 } 118 119 private class ScreenBrightnessModeSettingContainer extends SensorSettingContainer { 120 public ScreenBrightnessModeSettingContainer() { 121 super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_screen_brightness_mode); 122 } 123 124 @Override 125 public int getSettingMode(int defaultValue) { 126 return Settings.System.getInt( 127 mStateContainer.getContentResolver(), 128 Settings.System.SCREEN_BRIGHTNESS_MODE, 129 defaultValue); 130 } 131 } 132 133 private class AmbientDisplaySettingContainer extends SensorSettingContainer { 134 public AmbientDisplaySettingContainer() { 135 super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_ambient_display); 136 } 137 138 @Override 139 protected int getSettingMode(int defaultValue) { 140 // TODO: replace the use of reflection with Settings.Secure.DOZE_ENABLED when the 141 // static field is not hidden anymore 142 Class<?> secureSettingsClass = Settings.Secure.class; 143 Field dozeEnabledField; 144 try { 145 dozeEnabledField = secureSettingsClass.getField("DOZE_ENABLED"); 146 } catch (NoSuchFieldException e) { 147 return defaultValue; 148 } 149 150 String settingName; 151 try { 152 settingName = (String) dozeEnabledField.get(null /* obj */); 153 } catch (IllegalAccessException e) { 154 return defaultValue; 155 } 156 157 return Settings.Secure.getInt( 158 mStateContainer.getContentResolver(), 159 settingName, 160 defaultValue); 161 } 162 } 163 164 private class AutoRotateScreenModeSettingContainer extends SensorSettingContainer { 165 public AutoRotateScreenModeSettingContainer() { 166 super(Settings.ACTION_ACCESSIBILITY_SETTINGS, 167 R.string.snsr_setting_auto_rotate_screen_mode); 168 } 169 170 @Override 171 protected int getSettingMode(int defaultValue) { 172 return Settings.System.getInt( 173 mStateContainer.getContentResolver(), 174 Settings.System.ACCELEROMETER_ROTATION, 175 defaultValue); 176 } 177 } 178 179 private class KeepScreenOnModeSettingContainer extends SensorSettingContainer { 180 public KeepScreenOnModeSettingContainer() { 181 super(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS, 182 R.string.snsr_setting_keep_screen_on); 183 } 184 185 @Override 186 protected int getSettingMode(int defaultValue) { 187 return Settings.Global.getInt( 188 mStateContainer.getContentResolver(), 189 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 190 defaultValue); 191 } 192 } 193 194 private class LocationModeSettingContainer extends SensorSettingContainer { 195 public LocationModeSettingContainer() { 196 super(Settings.ACTION_LOCATION_SOURCE_SETTINGS, R.string.snsr_setting_location_mode); 197 } 198 199 @Override 200 protected int getSettingMode(int defaultValue) { 201 return Settings.Secure.getInt( 202 mStateContainer.getContentResolver(), 203 Settings.Secure.LOCATION_MODE, 204 defaultValue); 205 } 206 } 207 } 208