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 
requestToRestoreFeatures()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 
captureInitialState()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 {
AirplaneModeSettingContainer()94         public AirplaneModeSettingContainer() {
95             super(Settings.ACTION_AIRPLANE_MODE_SETTINGS, R.string.snsr_setting_airplane_mode);
96         }
97 
98         @Override
getSettingMode(int defaultValue)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
isSettingAvailable()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 {
ScreenBrightnessModeSettingContainer()120         public ScreenBrightnessModeSettingContainer() {
121             super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_screen_brightness_mode);
122         }
123 
124         @Override
getSettingMode(int defaultValue)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 {
AmbientDisplaySettingContainer()134         public AmbientDisplaySettingContainer() {
135             super(Settings.ACTION_DISPLAY_SETTINGS, R.string.snsr_setting_ambient_display);
136         }
137 
138         @Override
getSettingMode(int defaultValue)139         protected int getSettingMode(int defaultValue) {
140             return Settings.Secure.getInt(
141                     mStateContainer.getContentResolver(),
142                     Settings.Secure.DOZE_ENABLED,
143                     defaultValue);
144         }
145     }
146 
147     private class AutoRotateScreenModeSettingContainer extends SensorSettingContainer {
AutoRotateScreenModeSettingContainer()148         public AutoRotateScreenModeSettingContainer() {
149             super(Settings.ACTION_ACCESSIBILITY_SETTINGS,
150                     R.string.snsr_setting_auto_rotate_screen_mode);
151         }
152 
153         @Override
getSettingMode(int defaultValue)154         protected int getSettingMode(int defaultValue) {
155             return Settings.System.getInt(
156                     mStateContainer.getContentResolver(),
157                     Settings.System.ACCELEROMETER_ROTATION,
158                     defaultValue);
159         }
160     }
161 
162     private class KeepScreenOnModeSettingContainer extends SensorSettingContainer {
KeepScreenOnModeSettingContainer()163         public KeepScreenOnModeSettingContainer() {
164             super(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS,
165                     R.string.snsr_setting_keep_screen_on);
166         }
167 
168         @Override
getSettingMode(int defaultValue)169         protected int getSettingMode(int defaultValue) {
170             return Settings.Global.getInt(
171                     mStateContainer.getContentResolver(),
172                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
173                     defaultValue);
174         }
175     }
176 
177     private class LocationModeSettingContainer extends SensorSettingContainer {
LocationModeSettingContainer()178         public LocationModeSettingContainer() {
179             super(Settings.ACTION_LOCATION_SOURCE_SETTINGS, R.string.snsr_setting_location_mode);
180         }
181 
182         @Override
getSettingMode(int defaultValue)183         protected int getSettingMode(int defaultValue) {
184             return Settings.Secure.getInt(
185                     mStateContainer.getContentResolver(),
186                     Settings.Secure.LOCATION_MODE,
187                     defaultValue);
188         }
189     }
190 }
191