Home | History | Annotate | Download | only in helpers
      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