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 
SensorFeaturesDeactivator(ISensorTestStateContainer stateContainer)49     public SensorFeaturesDeactivator(ISensorTestStateContainer stateContainer) {
50         mStateContainer = stateContainer;
51     }
52 
requestDeactivationOfFeatures()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 
requestToSetLocationMode(boolean state)69     public synchronized void requestToSetLocationMode(boolean state) throws InterruptedException {
70         mLocationMode.captureInitialState();
71         mLocationMode.requestToSetMode(mStateContainer, state);
72     }
73 
requestToRestoreFeatures()74     public synchronized void requestToRestoreFeatures() throws InterruptedException {
75         if (Thread.currentThread().isInterrupted()) {
76             // TODO: in the future, if the thread is interrupted, we might need to serialize the
77             //       intermediate state we acquired so we can restore when we have a chance
78             return;
79         }
80 
81         mAirplaneMode.requestToResetMode(mStateContainer);
82         mScreenBrightnessMode.requestToResetMode(mStateContainer);
83         mAmbientDisplayMode.requestToResetMode(mStateContainer);
84         mAutoRotateScreenMode.requestToResetMode(mStateContainer);
85         mKeepScreenOnMode.requestToResetMode(mStateContainer);
86         mLocationMode.requestToResetMode(mStateContainer);
87     }
88 
captureInitialState()89     private void captureInitialState() {
90         mAirplaneMode.captureInitialState();
91         mScreenBrightnessMode.captureInitialState();
92         mAmbientDisplayMode.captureInitialState();
93         mAutoRotateScreenMode.captureInitialState();
94         mLocationMode.captureInitialState();
95         mKeepScreenOnMode.captureInitialState();
96     }
97 
98     private class AirplaneModeSettingContainer extends SensorSettingContainer {
AirplaneModeSettingContainer()99         public AirplaneModeSettingContainer() {
100             super(Settings.ACTION_AIRPLANE_MODE_SETTINGS, R.string.snsr_setting_airplane_mode);
101         }
102 
103         @Override
getSettingMode(int defaultValue)104         protected int getSettingMode(int defaultValue) {
105             ContentResolver contentResolver = mStateContainer.getContentResolver();
106             // Settings.System.AIRPLANE_MODE_ON is deprecated in API 17
107             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
108                 return Settings.System
109                         .getInt(contentResolver, Settings.System.AIRPLANE_MODE_ON, defaultValue);
110             } else {
111                 return Settings.Global
112                         .getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, defaultValue);
113             }
114         }
115 
116         @Override
isSettingAvailable()117         protected boolean isSettingAvailable() {
118             // call base first, lean back UI device does not have airplane mode
119             return super.isSettingAvailable() &&
120                     !(mStateContainer.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
121         }
122     }
123 
124     private class ScreenBrightnessModeSettingContainer extends SensorSettingContainer {
ScreenBrightnessModeSettingContainer()125         public ScreenBrightnessModeSettingContainer() {
126             super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_screen_brightness_mode);
127         }
128 
129         @Override
getSettingMode(int defaultValue)130         public int getSettingMode(int defaultValue) {
131             return Settings.System.getInt(
132                     mStateContainer.getContentResolver(),
133                     Settings.System.SCREEN_BRIGHTNESS_MODE,
134                     defaultValue);
135         }
136     }
137 
138     private class AmbientDisplaySettingContainer extends SensorSettingContainer {
AmbientDisplaySettingContainer()139         public AmbientDisplaySettingContainer() {
140             super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_ambient_display);
141         }
142 
143         @Override
getSettingMode(int defaultValue)144         protected int getSettingMode(int defaultValue) {
145             return Settings.Secure.getInt(
146                     mStateContainer.getContentResolver(),
147                     Settings.Secure.DOZE_ENABLED,
148                     defaultValue);
149         }
150     }
151 
152     private class AutoRotateScreenModeSettingContainer extends SensorSettingContainer {
AutoRotateScreenModeSettingContainer()153         public AutoRotateScreenModeSettingContainer() {
154             super(Settings.ACTION_ACCESSIBILITY_SETTINGS,
155                     R.string.snsr_setting_auto_rotate_screen_mode);
156         }
157 
158         @Override
getSettingMode(int defaultValue)159         protected int getSettingMode(int defaultValue) {
160             return Settings.System.getInt(
161                     mStateContainer.getContentResolver(),
162                     Settings.System.ACCELEROMETER_ROTATION,
163                     defaultValue);
164         }
165     }
166 
167     private class KeepScreenOnModeSettingContainer extends SensorSettingContainer {
KeepScreenOnModeSettingContainer()168         public KeepScreenOnModeSettingContainer() {
169             super(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS,
170                     R.string.snsr_setting_keep_screen_on);
171         }
172 
173         @Override
getSettingMode(int defaultValue)174         protected int getSettingMode(int defaultValue) {
175             return Settings.Global.getInt(
176                     mStateContainer.getContentResolver(),
177                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
178                     defaultValue);
179         }
180     }
181 
182     private class LocationModeSettingContainer extends SensorSettingContainer {
LocationModeSettingContainer()183         public LocationModeSettingContainer() {
184             super(Settings.ACTION_LOCATION_SOURCE_SETTINGS, R.string.snsr_setting_location_mode);
185         }
186 
187         @Override
getSettingMode(int defaultValue)188         protected int getSettingMode(int defaultValue) {
189             return Settings.Secure.getInt(
190                     mStateContainer.getContentResolver(),
191                     Settings.Secure.LOCATION_MODE,
192                     defaultValue);
193         }
194     }
195 }
196