Home | History | Annotate | Download | only in targetprep
      1 /*
      2  * Copyright (C) 2010 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.tradefed.targetprep;
     18 
     19 import com.android.ddmlib.IDevice;
     20 import com.android.tradefed.build.IBuildInfo;
     21 import com.android.tradefed.config.Option;
     22 import com.android.tradefed.config.OptionClass;
     23 import com.android.tradefed.device.DeviceNotAvailableException;
     24 import com.android.tradefed.device.ITestDevice;
     25 import com.android.tradefed.device.StubDevice;
     26 import com.android.tradefed.log.LogUtil.CLog;
     27 import com.android.tradefed.util.BinaryState;
     28 import com.android.tradefed.util.MultiMap;
     29 
     30 import com.google.common.annotations.VisibleForTesting;
     31 
     32 import java.io.File;
     33 import java.util.ArrayList;
     34 import java.util.Collection;
     35 import java.util.HashMap;
     36 import java.util.List;
     37 import java.util.Map;
     38 
     39 /**
     40  * A {@link ITargetPreparer} that configures a device for testing based on provided {@link Option}s.
     41  *
     42  * <p>Requires a device where 'adb root' is possible, typically a userdebug build type.
     43  *
     44  * <p>Should be performed <strong>after</strong> a new build is flashed.
     45  */
     46 @OptionClass(alias = "device-setup")
     47 public class DeviceSetup extends BaseTargetPreparer implements ITargetCleaner {
     48 
     49     // Networking
     50     @Option(name = "airplane-mode",
     51             description = "Turn airplane mode on or off")
     52     protected BinaryState mAirplaneMode = BinaryState.IGNORE;
     53     // ON:  settings put global airplane_mode_on 1
     54     //      am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true
     55     // OFF: settings put global airplane_mode_on 0
     56     //      am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false
     57 
     58     @Option(name = "data", description = "Turn mobile data on or off")
     59     protected BinaryState mData = BinaryState.IGNORE;
     60     // ON:  settings put global mobile_data 1
     61     //      svc data enable
     62     // OFF: settings put global mobile_data 0
     63     //      svc data disable
     64 
     65     @Option(name = "cell", description = "Turn cellular radio on or off")
     66     protected BinaryState mCell = BinaryState.IGNORE;
     67     // ON:  settings put global cell_on 1
     68     // OFF: settings put global cell_on 0
     69 
     70     @Option(name = "cell-auto-setting", description = "Turn wear cellular mediator on or off")
     71     protected BinaryState mCellAutoSetting = BinaryState.IGNORE;
     72     // ON:  settings put global clockwork_cell_auto_setting 1
     73     // OFF: settings put global clockwork_cell_auto_setting 0
     74 
     75     @Option(name = "wifi", description = "Turn wifi on or off")
     76     protected BinaryState mWifi = BinaryState.IGNORE;
     77     // ON:  settings put global wifi_on 1
     78     //      svc wifi enable
     79     // OFF: settings put global wifi_off 0
     80     //      svc wifi disable
     81 
     82     @Option(name = "wifi-network",
     83             description = "The SSID of the network to connect to. Will only attempt to " +
     84             "connect to a network if set")
     85     protected String mWifiSsid = null;
     86 
     87     @Option(name = "wifi-psk",
     88             description = "The passphrase used to connect to a secured network")
     89     protected String mWifiPsk = null;
     90 
     91     @Option(name = "wifi-watchdog",
     92             description = "Turn wifi watchdog on or off")
     93     protected BinaryState mWifiWatchdog = BinaryState.IGNORE;
     94     // ON:  settings put global wifi_watchdog 1
     95     // OFF: settings put global wifi_watchdog 0
     96 
     97     @Option(name = "disable-cw-wifi-mediator", description = "Turn wifi mediator on or off")
     98     protected BinaryState mDisableCwWifiMediator = BinaryState.IGNORE;
     99     // ON:  settings put global cw_disable_wifimediator 1
    100     // OFF: settings put global cw_disable_wifimediator 0
    101 
    102     @Option(
    103         name = "wifi-scan-always-enabled",
    104         description = "Turn wifi scan always enabled on or off"
    105     )
    106     protected BinaryState mWifiScanAlwaysEnabled = BinaryState.IGNORE;
    107     // ON:  settings put global wifi_scan_always_enabled 1
    108     // OFF: settings put global wifi_scan_always_enabled 0
    109 
    110     @Option(name = "ethernet",
    111             description = "Turn ethernet on or off")
    112     protected BinaryState mEthernet = BinaryState.IGNORE;
    113     // ON:  ifconfig eth0 up
    114     // OFF: ifconfig eth0 down
    115 
    116     @Option(name = "bluetooth",
    117             description = "Turn bluetooth on or off")
    118     protected BinaryState mBluetooth = BinaryState.IGNORE;
    119     // ON:  service call bluetooth_manager 6
    120     // OFF: service call bluetooth_manager 8
    121 
    122     @Option(name = "nfc",
    123             description = "Turn nfc on or off")
    124     protected BinaryState mNfc = BinaryState.IGNORE;
    125     // ON:  svc nfc enable
    126     // OFF: svc nfc disable
    127 
    128     // Screen
    129     @Option(name = "screen-adaptive-brightness",
    130             description = "Turn screen adaptive brightness on or off")
    131     protected BinaryState mScreenAdaptiveBrightness = BinaryState.IGNORE;
    132     // ON:  settings put system screen_brightness_mode 1
    133     // OFF: settings put system screen_brightness_mode 0
    134 
    135     @Option(name = "screen-brightness",
    136             description = "Set the screen brightness. This is uncalibrated from product to product")
    137     protected Integer mScreenBrightness = null;
    138     // settings put system screen_brightness $N
    139 
    140     @Option(name = "screen-always-on",
    141             description = "Turn 'screen always on' on or off. If ON, then screen-timeout-secs " +
    142             "must be unset. Will only work when the device is plugged in")
    143     protected BinaryState mScreenAlwaysOn = BinaryState.ON;
    144     // ON:  svc power stayon true
    145     // OFF: svc power stayon false
    146 
    147     @Option(name = "screen-timeout-secs",
    148             description = "Set the screen timeout in seconds. If set, then screen-always-on must " +
    149             "be OFF or DEFAULT")
    150     protected Long mScreenTimeoutSecs = null;
    151     // settings put system screen_off_timeout $(N * 1000)
    152 
    153     @Option(name = "screen-ambient-mode",
    154             description = "Turn screen ambient mode on or off")
    155     protected BinaryState mScreenAmbientMode = BinaryState.IGNORE;
    156     // ON:  settings put secure doze_enabled 1
    157     // OFF: settings put secure doze_enabled 0
    158 
    159     @Option(name = "wake-gesture",
    160             description = "Turn wake gesture on or off")
    161     protected BinaryState mWakeGesture = BinaryState.IGNORE;
    162     // ON:  settings put secure wake_gesture_enabled 1
    163     // OFF: settings put secure wake_gesture_enabled 0
    164 
    165     @Option(name = "screen-saver",
    166             description = "Turn screen saver on or off")
    167     protected BinaryState mScreenSaver = BinaryState.IGNORE;
    168     // ON:  settings put secure screensaver_enabled 1
    169     // OFF: settings put secure screensaver_enabled 0
    170 
    171     @Option(name = "notification-led",
    172             description = "Turn the notification led on or off")
    173     protected BinaryState mNotificationLed = BinaryState.IGNORE;
    174     // ON:  settings put system notification_light_pulse 1
    175     // OFF: settings put system notification_light_pulse 0
    176 
    177     @Option(name = "install-non-market-apps",
    178             description = "Allow or prevent non-market app to initiate an apk install request")
    179     protected BinaryState mInstallNonMarketApps = BinaryState.IGNORE;
    180     // ON:  settings put secure install_non_market_apps 1
    181     // OFF: settings put secure install_non_market_apps 0
    182 
    183     // Media
    184     @Option(name = "trigger-media-mounted",
    185             description = "Trigger a MEDIA_MOUNTED broadcast")
    186     protected boolean mTriggerMediaMounted = false;
    187     // am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://${EXTERNAL_STORAGE}
    188     // --receiver-include-background
    189 
    190     // Location
    191     @Option(name = "location-gps", description = "Turn the GPS location on or off")
    192     protected BinaryState mLocationGps = BinaryState.IGNORE;
    193     // ON:  settings put secure location_providers_allowed +gps
    194     // OFF: settings put secure location_providers_allowed -gps
    195 
    196     @Option(name = "location-network",
    197             description = "Turn the network location on or off")
    198     protected BinaryState mLocationNetwork = BinaryState.IGNORE;
    199     // ON:  settings put secure location_providers_allowed +network
    200     // OFF: settings put secure location_providers_allowed -network
    201 
    202     // Sensor
    203     @Option(name = "auto-rotate",
    204             description = "Turn auto rotate on or off")
    205     protected BinaryState mAutoRotate = BinaryState.IGNORE;
    206     // ON:  settings put system accelerometer_rotation 1
    207     // OFF: settings put system accelerometer_rotation 0
    208 
    209     // Power
    210     @Option(name = "battery-saver-mode",
    211             description = "Turn battery saver mode manually on or off. If OFF but battery is " +
    212             "less battery-saver-trigger, the device will still go into battery saver mode")
    213     protected BinaryState mBatterySaver = BinaryState.IGNORE;
    214     // ON:  dumpsys battery set usb 0
    215     //      settings put global low_power 1
    216     // OFF: settings put global low_power 0
    217 
    218     @Option(name = "battery-saver-trigger",
    219             description = "Set the battery saver trigger level. Should be [1-99] to enable, or " +
    220             "0 to disable automatic battery saver mode")
    221     protected Integer mBatterySaverTrigger = null;
    222     // settings put global low_power_trigger_level $N
    223 
    224     @Option(name = "enable-full-battery-stats-history",
    225             description = "Enable full history for batterystats. This option is only " +
    226             "applicable for L+")
    227     protected boolean mEnableFullBatteryStatsHistory = false;
    228     // dumpsys batterystats --enable full-history
    229 
    230     @Option(name = "disable-doze",
    231             description = "Disable device from going into doze mode. This option is only " +
    232             "applicable for M+")
    233     protected boolean mDisableDoze = false;
    234     // dumpsys deviceidle disable
    235 
    236     // Time
    237     @Option(name = "auto-update-time",
    238             description = "Turn auto update time on or off")
    239     protected BinaryState mAutoUpdateTime = BinaryState.IGNORE;
    240     // ON:  settings put global auto_time 1
    241     // OFF: settings put global auto_time 0
    242 
    243     @Option(name = "auto-update-timezone", description = "Turn auto update timezone on or off")
    244     protected BinaryState mAutoUpdateTimezone = BinaryState.IGNORE;
    245     // ON:  settings put global auto_timezone 1
    246     // OFF: settings put global auto_timezone 0
    247 
    248     @Option(
    249         name = "set-timezone",
    250         description =
    251                 "Set timezone property by TZ name "
    252                         + "(http://en.wikipedia.org/wiki/List_of_tz_database_time_zones)"
    253     )
    254     protected String mTimezone = null;
    255 
    256     // Calling
    257     @Option(name = "disable-dialing",
    258             description = "Disable dialing")
    259     protected boolean mDisableDialing = true;
    260     // setprop ro.telephony.disable-call true"
    261 
    262     @Option(name = "default-sim-data",
    263             description = "Set the default sim card slot for data. Leave unset for single SIM " +
    264             "devices")
    265     protected Integer mDefaultSimData = null;
    266     // settings put global multi_sim_data_call $N
    267 
    268     @Option(name = "default-sim-voice",
    269             description = "Set the default sim card slot for voice calls. Leave unset for single " +
    270             "SIM devices")
    271     protected Integer mDefaultSimVoice = null;
    272     // settings put global multi_sim_voice_call $N
    273 
    274     @Option(name = "default-sim-sms",
    275             description = "Set the default sim card slot for SMS. Leave unset for single SIM " +
    276             "devices")
    277     protected Integer mDefaultSimSms = null;
    278     // settings put global multi_sim_sms $N
    279 
    280     // Audio
    281     private static final boolean DEFAULT_DISABLE_AUDIO = true;
    282     @Option(name = "disable-audio",
    283             description = "Disable the audio")
    284     protected boolean mDisableAudio = DEFAULT_DISABLE_AUDIO;
    285     // setprop ro.audio.silent 1"
    286 
    287     @Option(name = "force-skip-system-props",
    288             description = "Force setup to not modify any device system properties. All other " +
    289             "system property options will be ignored")
    290     protected boolean mForceSkipSystemProps = false;
    291 
    292     @Option(name = "force-skip-settings",
    293             description = "Force setup to not modify any device settings. All other setting " +
    294             "options will be ignored.")
    295     protected boolean mForceSkipSettings = false;
    296 
    297     @Option(name = "force-skip-run-commands",
    298             description = "Force setup to not run any additional commands. All other commands " +
    299             "will be ignored.")
    300     protected boolean mForceSkipRunCommands = false;
    301 
    302     @Option(name = "set-test-harness",
    303             description = "Set the read-only test harness flag on boot")
    304     protected boolean mSetTestHarness = true;
    305     // setprop ro.monkey 1
    306     // setprop ro.test_harness 1
    307 
    308     @Option(name = "disable-dalvik-verifier",
    309             description = "Disable the dalvik verifier on device. Allows package-private " +
    310             "framework tests to run.")
    311     protected boolean mDisableDalvikVerifier = false;
    312     // setprop dalvik.vm.dexopt-flags v=n
    313 
    314     @Option(name = "set-property",
    315             description = "Set the specified property on boot. Option may be repeated but only " +
    316             "the last value for a given key will be set.")
    317     protected Map<String, String> mSetProps = new HashMap<>();
    318 
    319     @Option(
    320         name = "restore-properties",
    321         description =
    322                 "Restore previous /data/local.prop on tear down, restoring any properties DeviceSetup changed by modifying /data/local.prop."
    323     )
    324     protected boolean mRestoreProperties = false;
    325 
    326     protected File mPreviousProperties;
    327 
    328     @Option(name = "set-system-setting",
    329             description = "Change a system (non-secure) setting. Option may be repeated and all " +
    330             "key/value pairs will be set in order.")
    331     // Use a Multimap since it is possible for a setting to have multiple values for the same key
    332     protected MultiMap<String, String> mSystemSettings = new MultiMap<>();
    333 
    334     @Option(name = "set-secure-setting",
    335             description = "Change a secure setting. Option may be repeated and all key/value " +
    336             "pairs will be set in order.")
    337     // Use a Multimap since it is possible for a setting to have multiple values for the same key
    338     protected MultiMap<String, String> mSecureSettings = new MultiMap<>();
    339 
    340     @Option(name = "set-global-setting",
    341             description = "Change a global setting. Option may be repeated and all key/value " +
    342             "pairs will be set in order.")
    343     // Use a Multimap since it is possible for a setting to have multiple values for the same key
    344     protected MultiMap<String, String> mGlobalSettings = new MultiMap<>();
    345 
    346     @Option(
    347         name = "restore-settings",
    348         description = "Restore settings modified by this preparer on tear down."
    349     )
    350     protected boolean mRestoreSettings = false;
    351 
    352     private Map<String, String> mPreviousSystemSettings = new HashMap<>();
    353     private Map<String, String> mPreviousSecureSettings = new HashMap<>();
    354     private Map<String, String> mPreviousGlobalSettings = new HashMap<>();
    355 
    356     protected List<String> mRunCommandBeforeSettings = new ArrayList<>();
    357 
    358     @Option(name = "run-command",
    359             description = "Run an adb shell command. Option may be repeated")
    360     protected List<String> mRunCommandAfterSettings = new ArrayList<>();
    361 
    362     @Option(name = "disconnect-wifi-after-test",
    363             description = "Disconnect from wifi network after test completes.")
    364     private boolean mDisconnectWifiAfterTest = true;
    365 
    366     private static final long DEFAULT_MIN_EXTERNAL_STORAGE_KB = 500;
    367     @Option(name = "min-external-storage-kb",
    368             description="The minimum amount of free space in KB that must be present on device's " +
    369             "external storage.")
    370     protected long mMinExternalStorageKb = DEFAULT_MIN_EXTERNAL_STORAGE_KB;
    371 
    372     @Option(name = "local-data-path",
    373             description = "Optional local file path of test data to sync to device's external " +
    374             "storage. Use --remote-data-path to set remote location.")
    375     protected File mLocalDataFile = null;
    376 
    377     @Option(name = "remote-data-path",
    378             description = "Optional file path on device's external storage to sync test data. " +
    379             "Must be used with --local-data-path.")
    380     protected String mRemoteDataPath = null;
    381 
    382     // Deprecated options follow
    383     /**
    384      * @deprecated use min-external-storage-kb instead.
    385      */
    386     @Option(name = "min-external-store-space",
    387             description = "deprecated, use option min-external-storage-kb. The minimum amount of " +
    388             "free space in KB that must be present on device's external storage.")
    389     @Deprecated
    390     private long mDeprecatedMinExternalStoreSpace = DEFAULT_MIN_EXTERNAL_STORAGE_KB;
    391 
    392     /**
    393      * @deprecated use option disable-audio instead.
    394      */
    395     @Option(name = "audio-silent",
    396             description = "deprecated, use option disable-audio. set ro.audio.silent on boot.")
    397     @Deprecated
    398     private boolean mDeprecatedSetAudioSilent = DEFAULT_DISABLE_AUDIO;
    399 
    400     /**
    401      * @deprecated use option set-property instead.
    402      */
    403     @Option(name = "setprop",
    404             description = "deprecated, use option set-property. set the specified property on " +
    405             "boot. Format: --setprop key=value. May be repeated.")
    406     @Deprecated
    407     private Collection<String> mDeprecatedSetProps = new ArrayList<String>();
    408 
    409     private static final String PERSIST_PREFIX = "persist.";
    410 
    411     /**
    412      * {@inheritDoc}
    413      */
    414     @Override
    415     public void setUp(ITestDevice device, IBuildInfo buildInfo) throws DeviceNotAvailableException,
    416             TargetSetupError {
    417         if (isDisabled()) {
    418             return;
    419         }
    420 
    421         CLog.i("Performing setup on %s", device.getSerialNumber());
    422 
    423         if (device.getOptions().isEnableAdbRoot() && !device.enableAdbRoot()) {
    424             throw new TargetSetupError(String.format("Failed to enable adb root on %s",
    425                     device.getSerialNumber()), device.getDeviceDescriptor());
    426         }
    427 
    428         // Convert deprecated options into current options
    429         processDeprecatedOptions(device);
    430         // Convert options into settings and run commands
    431         processOptions(device);
    432         // Change system props (will reboot device)
    433         changeSystemProps(device);
    434         // Handle screen always on setting
    435         handleScreenAlwaysOnSetting(device);
    436         // Run commands designated to be run before changing settings
    437         runCommands(device, mRunCommandBeforeSettings);
    438         // Change settings
    439         changeSettings(device);
    440         // Connect wifi after settings since this may take a while
    441         connectWifi(device);
    442         // Sync data after settings since this may take a while
    443         syncTestData(device);
    444         // Run commands designated to be run after changing settings
    445         runCommands(device, mRunCommandAfterSettings);
    446         // Throw an error if there is not enough storage space
    447         checkExternalStoreSpace(device);
    448 
    449         device.clearErrorDialogs();
    450     }
    451 
    452     /**
    453      * {@inheritDoc}
    454      */
    455     @Override
    456     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
    457             throws DeviceNotAvailableException {
    458         // ignore tearDown if it's a stub device, since there is no real device to clean.
    459         if (isDisabled() || device.getIDevice() instanceof StubDevice) {
    460             return;
    461         }
    462 
    463         CLog.i("Performing teardown on %s", device.getSerialNumber());
    464 
    465         if (e instanceof DeviceFailedToBootError) {
    466             CLog.d("boot failure: skipping teardown");
    467             return;
    468         }
    469 
    470         // Only try to disconnect if wifi ssid is set since isWifiEnabled() is a heavy operation
    471         // which should be avoided when possible
    472         if (mDisconnectWifiAfterTest && mWifiSsid != null && device.isWifiEnabled()) {
    473             boolean result = device.disconnectFromWifi();
    474             if (result) {
    475                 CLog.i("Successfully disconnected from wifi network on %s",
    476                         device.getSerialNumber());
    477             } else {
    478                 CLog.w("Failed to disconnect from wifi network on %s", device.getSerialNumber());
    479             }
    480         }
    481 
    482         if (mRestoreProperties) {
    483             if (mPreviousProperties != null) {
    484                 device.pushFile(mPreviousProperties, "/data/local.prop");
    485             } else {
    486                 device.executeShellCommand("rm -f /data/local.prop");
    487             }
    488             device.reboot();
    489         }
    490 
    491         if (mRestoreSettings) {
    492             for (Map.Entry<String, String> entry : mPreviousSystemSettings.entrySet()) {
    493                 device.setSetting("system", entry.getKey(), entry.getValue());
    494             }
    495             for (Map.Entry<String, String> entry : mPreviousGlobalSettings.entrySet()) {
    496                 device.setSetting("global", entry.getKey(), entry.getValue());
    497             }
    498             for (Map.Entry<String, String> entry : mPreviousSecureSettings.entrySet()) {
    499                 device.setSetting("secure", entry.getKey(), entry.getValue());
    500             }
    501         }
    502     }
    503 
    504     /**
    505      * Processes the deprecated options converting them into the currently used options.
    506      * <p>
    507      * This method should be run before any other processing methods. Will throw a
    508      * {@link TargetSetupError} if the deprecated option overrides a specified non-deprecated
    509      * option.
    510      * </p>
    511      * @throws TargetSetupError if there is a conflict
    512      */
    513     public void processDeprecatedOptions(ITestDevice device) throws TargetSetupError {
    514         if (mDeprecatedMinExternalStoreSpace != DEFAULT_MIN_EXTERNAL_STORAGE_KB) {
    515             if (mMinExternalStorageKb != DEFAULT_MIN_EXTERNAL_STORAGE_KB) {
    516                 throw new TargetSetupError("Deprecated option min-external-store-space conflicts " +
    517                         "with option min-external-storage-kb", device.getDeviceDescriptor());
    518             }
    519             mMinExternalStorageKb = mDeprecatedMinExternalStoreSpace;
    520         }
    521 
    522         if (mDeprecatedSetAudioSilent != DEFAULT_DISABLE_AUDIO) {
    523             if (mDisableAudio != DEFAULT_DISABLE_AUDIO) {
    524                 throw new TargetSetupError("Deprecated option audio-silent conflicts with " +
    525                         "option disable-audio", device.getDeviceDescriptor());
    526             }
    527             mDisableAudio = mDeprecatedSetAudioSilent;
    528         }
    529 
    530         if (!mDeprecatedSetProps.isEmpty()) {
    531             if (!mSetProps.isEmpty()) {
    532                 throw new TargetSetupError("Deprecated option setprop conflicts with option " +
    533                         "set-property ", device.getDeviceDescriptor());
    534             }
    535             for (String prop : mDeprecatedSetProps) {
    536                 String[] parts = prop.split("=", 2);
    537                 String key = parts[0].trim();
    538                 String value = parts.length == 2 ? parts[1].trim() : "";
    539                 mSetProps.put(key, value);
    540             }
    541         }
    542     }
    543 
    544     /**
    545      * Process all the {@link Option}s and turn them into system props, settings, or run commands.
    546      * Does not run any commands on the device at this time.
    547      * <p>
    548      * Exposed so that children classes may override this.
    549      * </p>
    550      *
    551      * @param device The {@link ITestDevice}
    552      * @throws DeviceNotAvailableException if the device is not available
    553      * @throws TargetSetupError if the {@link Option}s conflict
    554      */
    555     public void processOptions(ITestDevice device) throws DeviceNotAvailableException,
    556             TargetSetupError {
    557         setSettingForBinaryState(mData, mGlobalSettings, "mobile_data", "1", "0");
    558         setCommandForBinaryState(
    559                 mData, mRunCommandAfterSettings, "svc data enable", "svc data disable");
    560 
    561         setSettingForBinaryState(mCell, mGlobalSettings, "cell_on", "1", "0");
    562         setSettingForBinaryState(
    563                 mCellAutoSetting, mGlobalSettings, "clockwork_cell_auto_setting", "1", "0");
    564 
    565         setSettingForBinaryState(mWifi, mGlobalSettings, "wifi_on", "1", "0");
    566         setCommandForBinaryState(
    567                 mWifi, mRunCommandAfterSettings, "svc wifi enable", "svc wifi disable");
    568 
    569         setSettingForBinaryState(mWifiWatchdog, mGlobalSettings, "wifi_watchdog", "1", "0");
    570         setSettingForBinaryState(
    571                 mDisableCwWifiMediator, mGlobalSettings, "cw_disable_wifimediator", "1", "0");
    572 
    573         setSettingForBinaryState(mWifiScanAlwaysEnabled, mGlobalSettings,
    574                 "wifi_scan_always_enabled", "1", "0");
    575 
    576         setCommandForBinaryState(mEthernet, mRunCommandAfterSettings,
    577                 "ifconfig eth0 up", "ifconfig eth0 down");
    578 
    579         setCommandForBinaryState(mBluetooth, mRunCommandAfterSettings,
    580                 "service call bluetooth_manager 6", "service call bluetooth_manager 8");
    581 
    582         setCommandForBinaryState(mNfc, mRunCommandAfterSettings,
    583                 "svc nfc enable", "svc nfc disable");
    584 
    585         if (mScreenBrightness != null && BinaryState.ON.equals(mScreenAdaptiveBrightness)) {
    586             throw new TargetSetupError("Option screen-brightness cannot be set when " +
    587                     "screen-adaptive-brightness is set to ON", device.getDeviceDescriptor());
    588         }
    589 
    590         setSettingForBinaryState(mScreenAdaptiveBrightness, mSystemSettings,
    591                 "screen_brightness_mode", "1", "0");
    592 
    593         if (mScreenBrightness != null) {
    594             mSystemSettings.put("screen_brightness", Integer.toString(mScreenBrightness));
    595         }
    596 
    597         if (mScreenTimeoutSecs != null) {
    598             mSystemSettings.put("screen_off_timeout", Long.toString(mScreenTimeoutSecs * 1000));
    599         }
    600 
    601         setSettingForBinaryState(mScreenAmbientMode, mSecureSettings, "doze_enabled", "1", "0");
    602 
    603         setSettingForBinaryState(mWakeGesture, mSecureSettings, "wake_gesture_enabled", "1", "0");
    604 
    605         setSettingForBinaryState(mScreenSaver, mSecureSettings, "screensaver_enabled", "1", "0");
    606 
    607         setSettingForBinaryState(mNotificationLed, mSystemSettings,
    608                 "notification_light_pulse", "1", "0");
    609 
    610         setSettingForBinaryState(mInstallNonMarketApps, mSecureSettings,
    611                 "install_non_market_apps", "1", "0");
    612 
    613         if (mTriggerMediaMounted) {
    614             mRunCommandAfterSettings.add(
    615                     "am broadcast -a android.intent.action.MEDIA_MOUNTED -d "
    616                             + "file://${EXTERNAL_STORAGE} --receiver-include-background");
    617         }
    618 
    619         setSettingForBinaryState(mLocationGps, mSecureSettings,
    620                 "location_providers_allowed", "+gps", "-gps");
    621 
    622         setSettingForBinaryState(mLocationNetwork, mSecureSettings,
    623                 "location_providers_allowed", "+network", "-network");
    624 
    625         setSettingForBinaryState(mAutoRotate, mSystemSettings, "accelerometer_rotation", "1", "0");
    626 
    627         if (device.getApiLevel() < 22) {
    628             setCommandForBinaryState(mBatterySaver, mRunCommandBeforeSettings,
    629                 "dumpsys battery set usb 0", null);
    630         } else {
    631             setCommandForBinaryState(mBatterySaver, mRunCommandBeforeSettings,
    632                 "dumpsys battery unplug", null);
    633         }
    634         setSettingForBinaryState(mBatterySaver, mGlobalSettings, "low_power", "1", "0");
    635 
    636         if (mBatterySaverTrigger != null) {
    637             mGlobalSettings.put("low_power_trigger_level", Integer.toString(mBatterySaverTrigger));
    638         }
    639 
    640         if (mEnableFullBatteryStatsHistory) {
    641             mRunCommandAfterSettings.add("dumpsys batterystats --enable full-history");
    642         }
    643 
    644         if (mDisableDoze) {
    645             mRunCommandAfterSettings.add("dumpsys deviceidle disable");
    646         }
    647 
    648         setSettingForBinaryState(mAutoUpdateTime, mGlobalSettings, "auto_time", "1", "0");
    649 
    650         setSettingForBinaryState(mAutoUpdateTimezone, mGlobalSettings, "auto_timezone", "1", "0");
    651 
    652         if (mTimezone != null) {
    653             mSetProps.put("persist.sys.timezone", mTimezone);
    654         }
    655 
    656         if (mDisableDialing) {
    657             mSetProps.put("ro.telephony.disable-call", "true");
    658         }
    659 
    660         if (mDefaultSimData != null) {
    661             mGlobalSettings.put("multi_sim_data_call", Integer.toString(mDefaultSimData));
    662         }
    663 
    664         if (mDefaultSimVoice != null) {
    665             mGlobalSettings.put("multi_sim_voice_call", Integer.toString(mDefaultSimVoice));
    666         }
    667 
    668         if (mDefaultSimSms != null) {
    669             mGlobalSettings.put("multi_sim_sms", Integer.toString(mDefaultSimSms));
    670         }
    671 
    672         if (mDisableAudio) {
    673             mSetProps.put("ro.audio.silent", "1");
    674         }
    675 
    676         if (mSetTestHarness) {
    677             // set both ro.monkey and ro.test_harness, for compatibility with older platforms
    678             mSetProps.put("ro.monkey", "1");
    679             mSetProps.put("ro.test_harness", "1");
    680         }
    681 
    682         if (mDisableDalvikVerifier) {
    683             mSetProps.put("dalvik.vm.dexopt-flags", "v=n");
    684         }
    685     }
    686 
    687     /**
    688      * Change the system properties on the device.
    689      *
    690      * @param device The {@link ITestDevice}
    691      * @throws DeviceNotAvailableException if the device is not available
    692      * @throws TargetSetupError if there was a failure setting the system properties
    693      */
    694     private void changeSystemProps(ITestDevice device) throws DeviceNotAvailableException,
    695             TargetSetupError {
    696         if (mForceSkipSystemProps) {
    697             CLog.d("Skipping system props due to force-skip-system-props");
    698             return;
    699         }
    700 
    701         StringBuilder sb = new StringBuilder();
    702         for (Map.Entry<String, String> prop : mSetProps.entrySet()) {
    703             if (prop.getKey().startsWith(PERSIST_PREFIX)) {
    704                 String command = String.format("setprop \"%s\" \"%s\"",
    705                         prop.getKey(), prop.getValue());
    706                 device.executeShellCommand(command);
    707             } else {
    708                 sb.append(String.format("%s=%s\n", prop.getKey(), prop.getValue()));
    709             }
    710         }
    711 
    712         if (sb.length() == 0) {
    713             return;
    714         }
    715 
    716         if (mRestoreProperties) {
    717             mPreviousProperties = device.pullFile("/data/local.prop");
    718         }
    719         CLog.d("Pushing the following properties to /data/local.prop:\n%s", sb.toString());
    720         boolean result = device.pushString(sb.toString(), "/data/local.prop");
    721         if (!result) {
    722             throw new TargetSetupError(String.format("Failed to push /data/local.prop to %s",
    723                     device.getSerialNumber()), device.getDeviceDescriptor());
    724         }
    725         // Set reasonable permissions for /data/local.prop
    726         device.executeShellCommand("chmod 644 /data/local.prop");
    727         CLog.i("Rebooting %s due to system property change", device.getSerialNumber());
    728         device.reboot();
    729     }
    730 
    731     /**
    732      * Handles screen always on settings.
    733      * <p>
    734      * This is done in a dedicated function because special handling is required in case of setting
    735      * screen to always on.
    736      * @throws DeviceNotAvailableException
    737      */
    738     private void handleScreenAlwaysOnSetting(ITestDevice device)
    739             throws DeviceNotAvailableException {
    740         String cmd = "svc power stayon %s";
    741         switch (mScreenAlwaysOn) {
    742             case ON:
    743                 CLog.d("Setting screen always on to true");
    744                 device.executeShellCommand(String.format(cmd, "true"));
    745                 // send MENU press in case keygaurd needs to be dismissed again
    746                 device.executeShellCommand("input keyevent 82");
    747                 // send HOME press in case keyguard was already dismissed, so we bring device back
    748                 // to home screen
    749                 device.executeShellCommand("input keyevent 3");
    750                 break;
    751             case OFF:
    752                 CLog.d("Setting screen always on to false");
    753                 device.executeShellCommand(String.format(cmd, "false"));
    754                 break;
    755             case IGNORE:
    756                 break;
    757         }
    758     }
    759 
    760     /**
    761      * Change the settings on the device.
    762      * <p>
    763      * Exposed so children classes may override.
    764      * </p>
    765      *
    766      * @param device The {@link ITestDevice}
    767      * @throws DeviceNotAvailableException if the device is not available
    768      * @throws TargetSetupError if there was a failure setting the settings
    769      */
    770     public void changeSettings(ITestDevice device) throws DeviceNotAvailableException,
    771             TargetSetupError {
    772         if (mForceSkipSettings) {
    773             CLog.d("Skipping settings due to force-skip-setttings");
    774             return;
    775         }
    776 
    777         if (mSystemSettings.isEmpty() && mSecureSettings.isEmpty() && mGlobalSettings.isEmpty() &&
    778                 BinaryState.IGNORE.equals(mAirplaneMode)) {
    779             CLog.d("No settings to change");
    780             return;
    781         }
    782 
    783         if (device.getApiLevel() < 22) {
    784             throw new TargetSetupError(String.format("Changing setting not supported on %s, " +
    785                     "must be API 22+", device.getSerialNumber()), device.getDeviceDescriptor());
    786         }
    787 
    788         // Special case airplane mode since it needs to be set before other connectivity settings
    789         // For example, it is possible to enable airplane mode and then turn wifi on
    790         String command = "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state %s";
    791         switch (mAirplaneMode) {
    792             case ON:
    793                 CLog.d("Changing global setting airplane_mode_on to 1");
    794                 device.setSetting("global", "airplane_mode_on", "1");
    795                 if (!mForceSkipRunCommands) {
    796                     device.executeShellCommand(String.format(command, "true"));
    797                 }
    798                 break;
    799             case OFF:
    800                 CLog.d("Changing global setting airplane_mode_on to 0");
    801                 device.setSetting("global", "airplane_mode_on", "0");
    802                 if (!mForceSkipRunCommands) {
    803                     device.executeShellCommand(String.format(command, "false"));
    804                 }
    805                 break;
    806             case IGNORE:
    807                 // No-op
    808                 break;
    809         }
    810 
    811         for (String key : mSystemSettings.keySet()) {
    812             for (String value : mSystemSettings.get(key)) {
    813                 if (mRestoreSettings) {
    814                     String previousSetting = device.getSetting("system", key);
    815                     mPreviousSystemSettings.put(key, previousSetting);
    816                 }
    817                 CLog.d("Changing system setting %s to %s", key, value);
    818                 device.setSetting("system", key, value);
    819             }
    820         }
    821         for (String key : mSecureSettings.keySet()) {
    822             for (String value : mSecureSettings.get(key)) {
    823                 if (mRestoreSettings) {
    824                     String previousSetting = device.getSetting("secure", key);
    825                     mPreviousSecureSettings.put(key, previousSetting);
    826                 }
    827                 CLog.d("Changing secure setting %s to %s", key, value);
    828                 device.setSetting("secure", key, value);
    829             }
    830         }
    831 
    832         for (String key : mGlobalSettings.keySet()) {
    833             for (String value : mGlobalSettings.get(key)) {
    834                 if (mRestoreSettings) {
    835                     String previousSetting = device.getSetting("global", key);
    836                     mPreviousGlobalSettings.put(key, previousSetting);
    837                 }
    838                 CLog.d("Changing global setting %s to %s", key, value);
    839                 device.setSetting("global", key, value);
    840             }
    841         }
    842     }
    843 
    844     /**
    845      * Execute additional commands on the device.
    846      *
    847      * @param device The {@link ITestDevice}
    848      * @param commands The list of commands to run
    849      * @throws DeviceNotAvailableException if the device is not available
    850      * @throws TargetSetupError if there was a failure setting the settings
    851      */
    852     private void runCommands(ITestDevice device, List<String> commands)
    853             throws DeviceNotAvailableException, TargetSetupError {
    854         if (mForceSkipRunCommands) {
    855             CLog.d("Skipping run commands due to force-skip-run-commands");
    856             return;
    857         }
    858 
    859         for (String command : commands) {
    860             device.executeShellCommand(command);
    861         }
    862     }
    863 
    864     /**
    865      * Connects device to Wifi if SSID is specified.
    866      *
    867      * @param device The {@link ITestDevice}
    868      * @throws DeviceNotAvailableException if the device is not available
    869      * @throws TargetSetupError if there was a failure setting the settings
    870      */
    871     private void connectWifi(ITestDevice device) throws DeviceNotAvailableException,
    872             TargetSetupError {
    873         if (mForceSkipRunCommands) {
    874             CLog.d("Skipping connect wifi due to force-skip-run-commands");
    875             return;
    876         }
    877 
    878         if (mWifiSsid != null) {
    879             if (!device.connectToWifiNetwork(mWifiSsid, mWifiPsk)) {
    880                 throw new TargetSetupError(String.format(
    881                         "Failed to connect to wifi network %s on %s", mWifiSsid,
    882                         device.getSerialNumber()), device.getDeviceDescriptor());
    883             }
    884         }
    885     }
    886 
    887     /**
    888      * Syncs a set of test data files, specified via local-data-path, to devices external storage.
    889      *
    890      * @param device The {@link ITestDevice}
    891      * @throws DeviceNotAvailableException if the device is not available
    892      * @throws TargetSetupError if data fails to sync
    893      */
    894     private void syncTestData(ITestDevice device) throws DeviceNotAvailableException,
    895             TargetSetupError {
    896         if (mLocalDataFile == null) {
    897             return;
    898         }
    899 
    900         if (!mLocalDataFile.exists() || !mLocalDataFile.isDirectory()) {
    901             throw new TargetSetupError(String.format(
    902                     "local-data-path %s is not a directory", mLocalDataFile.getAbsolutePath()),
    903                     device.getDeviceDescriptor());
    904         }
    905         String fullRemotePath = device.getIDevice().getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
    906         if (fullRemotePath == null) {
    907             throw new TargetSetupError(String.format(
    908                     "failed to get external storage path on device %s", device.getSerialNumber()),
    909                     device.getDeviceDescriptor());
    910         }
    911         if (mRemoteDataPath != null) {
    912             fullRemotePath = String.format("%s/%s", fullRemotePath, mRemoteDataPath);
    913         }
    914         boolean result = device.syncFiles(mLocalDataFile, fullRemotePath);
    915         if (!result) {
    916             // TODO: get exact error code and respond accordingly
    917             throw new TargetSetupError(String.format(
    918                     "failed to sync test data from local-data-path %s to %s on device %s",
    919                     mLocalDataFile.getAbsolutePath(), fullRemotePath, device.getSerialNumber()),
    920                     device.getDeviceDescriptor());
    921         }
    922     }
    923 
    924     /**
    925      * Check that device external store has the required space
    926      *
    927      * @param device The {@link ITestDevice}
    928      * @throws DeviceNotAvailableException if the device is not available or if the device does not
    929      * have the required space
    930      */
    931     private void checkExternalStoreSpace(ITestDevice device) throws DeviceNotAvailableException {
    932         if (mMinExternalStorageKb <= 0) {
    933             return;
    934         }
    935 
    936         long freeSpace = device.getExternalStoreFreeSpace();
    937         if (freeSpace < mMinExternalStorageKb) {
    938             throw new DeviceNotAvailableException(String.format(
    939                     "External store free space %dK is less than required %dK for device %s",
    940                     freeSpace , mMinExternalStorageKb, device.getSerialNumber()),
    941                     device.getSerialNumber());
    942         }
    943     }
    944 
    945     /**
    946      * Helper method to add an ON/OFF setting to a setting map.
    947      *
    948      * @param state The {@link BinaryState}
    949      * @param settingsMap The {@link MultiMap} used to store the settings.
    950      * @param setting The setting key
    951      * @param onValue The value if ON
    952      * @param offValue The value if OFF
    953      */
    954     public static void setSettingForBinaryState(BinaryState state,
    955             MultiMap<String, String> settingsMap, String setting, String onValue, String offValue) {
    956         switch (state) {
    957             case ON:
    958                 settingsMap.put(setting, onValue);
    959                 break;
    960             case OFF:
    961                 settingsMap.put(setting, offValue);
    962                 break;
    963             case IGNORE:
    964                 // Do nothing
    965                 break;
    966         }
    967     }
    968 
    969     /**
    970      * Helper method to add an ON/OFF run command to be executed on the device.
    971      *
    972      * @param state The {@link BinaryState}
    973      * @param commands The list of commands to add the on or off command to.
    974      * @param onCommand The command to run if ON. Ignored if the command is {@code null}
    975      * @param offCommand The command to run if OFF. Ignored if the command is {@code null}
    976      */
    977     public static void setCommandForBinaryState(BinaryState state, List<String> commands,
    978             String onCommand, String offCommand) {
    979         switch (state) {
    980             case ON:
    981                 if (onCommand != null) {
    982                     commands.add(onCommand);
    983                 }
    984                 break;
    985             case OFF:
    986                 if (offCommand != null) {
    987                     commands.add(offCommand);
    988                 }
    989                 break;
    990             case IGNORE:
    991                 // Do nothing
    992                 break;
    993         }
    994     }
    995 
    996     /**
    997      * Exposed for unit testing
    998      */
    999     protected void setAirplaneMode(BinaryState airplaneMode) {
   1000         mAirplaneMode = airplaneMode;
   1001     }
   1002 
   1003     /* Exposed for unit testing */
   1004     @VisibleForTesting
   1005     protected void setData(BinaryState data) {
   1006         mData = data;
   1007     }
   1008 
   1009     /* Exposed for unit testing */
   1010     @VisibleForTesting
   1011     protected void setCell(BinaryState cell) {
   1012         mCell = cell;
   1013     }
   1014 
   1015     /* Exposed for unit testing */
   1016     @VisibleForTesting
   1017     protected void setCellAutoSetting(BinaryState cellAutoSetting) {
   1018         mCellAutoSetting = cellAutoSetting;
   1019     }
   1020 
   1021     /**
   1022      * Exposed for unit testing
   1023      */
   1024     protected void setWifi(BinaryState wifi) {
   1025         mWifi = wifi;
   1026     }
   1027 
   1028     /**
   1029      * Exposed for unit testing
   1030      */
   1031     protected void setWifiNetwork(String wifiNetwork) {
   1032         mWifiSsid = wifiNetwork;
   1033     }
   1034 
   1035     /**
   1036      * Exposed for unit testing
   1037      */
   1038     protected void setWifiWatchdog(BinaryState wifiWatchdog) {
   1039         mWifiWatchdog = wifiWatchdog;
   1040     }
   1041 
   1042     /* Exposed for unit testing */
   1043     @VisibleForTesting
   1044     protected void setDisableCwWifiMediator(BinaryState disableCwWifiMediator) {
   1045         mDisableCwWifiMediator = disableCwWifiMediator;
   1046     }
   1047 
   1048     /**
   1049      * Exposed for unit testing
   1050      */
   1051     protected void setWifiScanAlwaysEnabled(BinaryState wifiScanAlwaysEnabled) {
   1052         mWifiScanAlwaysEnabled = wifiScanAlwaysEnabled;
   1053     }
   1054 
   1055     /**
   1056      * Exposed for unit testing
   1057      */
   1058     protected void setEthernet(BinaryState ethernet) {
   1059         mEthernet = ethernet;
   1060     }
   1061 
   1062     /**
   1063      * Exposed for unit testing
   1064      */
   1065     protected void setBluetooth(BinaryState bluetooth) {
   1066         mBluetooth = bluetooth;
   1067     }
   1068 
   1069     /**
   1070      * Exposed for unit testing
   1071      */
   1072     protected void setNfc(BinaryState nfc) {
   1073         mNfc = nfc;
   1074     }
   1075 
   1076     /**
   1077      * Exposed for unit testing
   1078      */
   1079     protected void setScreenAdaptiveBrightness(BinaryState screenAdaptiveBrightness) {
   1080         mScreenAdaptiveBrightness = screenAdaptiveBrightness;
   1081     }
   1082 
   1083     /**
   1084      * Exposed for unit testing
   1085      */
   1086     protected void setScreenBrightness(Integer screenBrightness) {
   1087         mScreenBrightness = screenBrightness;
   1088     }
   1089 
   1090     /**
   1091      * Exposed for unit testing
   1092      */
   1093     protected void setScreenAlwaysOn(BinaryState screenAlwaysOn) {
   1094         mScreenAlwaysOn = screenAlwaysOn;
   1095     }
   1096 
   1097     /**
   1098      * Exposed for unit testing
   1099      */
   1100     protected void setScreenTimeoutSecs(Long screenTimeoutSecs) {
   1101         mScreenTimeoutSecs = screenTimeoutSecs;
   1102     }
   1103 
   1104     /**
   1105      * Exposed for unit testing
   1106      */
   1107     protected void setScreenAmbientMode(BinaryState screenAmbientMode) {
   1108         mScreenAmbientMode = screenAmbientMode;
   1109     }
   1110 
   1111     /**
   1112      * Exposed for unit testing
   1113      */
   1114     protected void setWakeGesture(BinaryState wakeGesture) {
   1115         mWakeGesture = wakeGesture;
   1116     }
   1117 
   1118     /**
   1119      * Exposed for unit testing
   1120      */
   1121     protected void setScreenSaver(BinaryState screenSaver) {
   1122         mScreenSaver = screenSaver;
   1123     }
   1124 
   1125     /**
   1126      * Exposed for unit testing
   1127      */
   1128     protected void setNotificationLed(BinaryState notificationLed) {
   1129         mNotificationLed = notificationLed;
   1130     }
   1131 
   1132     /**
   1133      * Exposed for unit testing
   1134      */
   1135     protected void setInstallNonMarketApps(BinaryState installNonMarketApps) {
   1136         mInstallNonMarketApps = installNonMarketApps;
   1137     }
   1138 
   1139     /**
   1140      * Exposed for unit testing
   1141      */
   1142     protected void setTriggerMediaMounted(boolean triggerMediaMounted) {
   1143         mTriggerMediaMounted = triggerMediaMounted;
   1144     }
   1145 
   1146     /**
   1147      * Exposed for unit testing
   1148      */
   1149     protected void setLocationGps(BinaryState locationGps) {
   1150         mLocationGps = locationGps;
   1151     }
   1152 
   1153     /**
   1154      * Exposed for unit testing
   1155      */
   1156     protected void setLocationNetwork(BinaryState locationNetwork) {
   1157         mLocationNetwork = locationNetwork;
   1158     }
   1159 
   1160     /**
   1161      * Exposed for unit testing
   1162      */
   1163     protected void setAutoRotate(BinaryState autoRotate) {
   1164         mAutoRotate = autoRotate;
   1165     }
   1166 
   1167     /**
   1168      * Exposed for unit testing
   1169      */
   1170     protected void setBatterySaver(BinaryState batterySaver) {
   1171         mBatterySaver = batterySaver;
   1172     }
   1173 
   1174     /**
   1175      * Exposed for unit testing
   1176      */
   1177     protected void setBatterySaverTrigger(Integer batterySaverTrigger) {
   1178         mBatterySaverTrigger = batterySaverTrigger;
   1179     }
   1180 
   1181     /**
   1182      * Exposed for unit testing
   1183      */
   1184     protected void setEnableFullBatteryStatsHistory(boolean enableFullBatteryStatsHistory) {
   1185         mEnableFullBatteryStatsHistory = enableFullBatteryStatsHistory;
   1186     }
   1187 
   1188     /**
   1189      * Exposed for unit testing
   1190      */
   1191     protected void setDisableDoze(boolean disableDoze) {
   1192         mDisableDoze = disableDoze;
   1193     }
   1194 
   1195     /**
   1196      * Exposed for unit testing
   1197      */
   1198     protected void setAutoUpdateTime(BinaryState autoUpdateTime) {
   1199         mAutoUpdateTime = autoUpdateTime;
   1200     }
   1201 
   1202     /**
   1203      * Exposed for unit testing
   1204      */
   1205     protected void setAutoUpdateTimezone(BinaryState autoUpdateTimezone) {
   1206         mAutoUpdateTimezone = autoUpdateTimezone;
   1207     }
   1208 
   1209     /**
   1210      * Exposed for unit testing
   1211      */
   1212     protected void setTimezone(String timezone) {
   1213         mTimezone = timezone;
   1214     }
   1215 
   1216     /**
   1217      * Exposed for unit testing
   1218      */
   1219     protected void setDisableDialing(boolean disableDialing) {
   1220         mDisableDialing = disableDialing;
   1221     }
   1222 
   1223     /**
   1224      * Exposed for unit testing
   1225      */
   1226     protected void setDefaultSimData(Integer defaultSimData) {
   1227         mDefaultSimData = defaultSimData;
   1228     }
   1229 
   1230     /**
   1231      * Exposed for unit testing
   1232      */
   1233     protected void setDefaultSimVoice(Integer defaultSimVoice) {
   1234         mDefaultSimVoice = defaultSimVoice;
   1235     }
   1236 
   1237     /**
   1238      * Exposed for unit testing
   1239      */
   1240     protected void setDefaultSimSms(Integer defaultSimSms) {
   1241         mDefaultSimSms = defaultSimSms;
   1242     }
   1243 
   1244     /**
   1245      * Exposed for unit testing
   1246      */
   1247     protected void setDisableAudio(boolean disable) {
   1248         mDisableAudio = disable;
   1249     }
   1250 
   1251     /**
   1252      * Exposed for unit testing
   1253      */
   1254     protected void setTestHarness(boolean setTestHarness) {
   1255         mSetTestHarness = setTestHarness;
   1256     }
   1257 
   1258     /**
   1259      * Exposed for unit testing
   1260      */
   1261     protected void setDisableDalvikVerifier(boolean disableDalvikVerifier) {
   1262         mDisableDalvikVerifier = disableDalvikVerifier;
   1263     }
   1264 
   1265     /**
   1266      * Exposed for unit testing
   1267      */
   1268     protected void setLocalDataPath(File path) {
   1269         mLocalDataFile = path;
   1270     }
   1271 
   1272     /**
   1273      * Exposed for unit testing
   1274      */
   1275     protected void setMinExternalStorageKb(long storageKb) {
   1276         mMinExternalStorageKb = storageKb;
   1277     }
   1278 
   1279     /**
   1280      * Exposed for unit testing
   1281      */
   1282     protected void setProperty(String key, String value) {
   1283         mSetProps.put(key, value);
   1284     }
   1285 
   1286     /** Exposed for unit testing */
   1287     public void setGlobalSetting(String key, String value) {
   1288         mGlobalSettings.put(key, value);
   1289     }
   1290 
   1291     /** Exposed for unit testing */
   1292     public void setSecureSetting(String key, String value) {
   1293         mSecureSettings.put(key, value);
   1294     }
   1295 
   1296     /** Exposed for unit testing */
   1297     public void setSystemSetting(String key, String value) {
   1298         mSystemSettings.put(key, value);
   1299     }
   1300 
   1301     /** Exposed for unit testing */
   1302     protected void setRestoreProperties(boolean restoreProperties) {
   1303         mRestoreProperties = restoreProperties;
   1304     }
   1305 
   1306     /** Exposed for unit testing */
   1307     protected void setRestoreSettings(boolean restoreSettings) {
   1308         mRestoreSettings = restoreSettings;
   1309     }
   1310 
   1311     /**
   1312      * Exposed for unit testing
   1313      * @deprecated use {@link #setMinExternalStorageKb(long)} instead.
   1314      */
   1315     @Deprecated
   1316     protected void setDeprecatedMinExternalStoreSpace(long storeSpace) {
   1317         mDeprecatedMinExternalStoreSpace = storeSpace;
   1318     }
   1319 
   1320     /**
   1321      * Exposed for unit testing
   1322      * @deprecated use {@link #setDisableAudio(boolean)} instead.
   1323      */
   1324     @Deprecated
   1325     protected void setDeprecatedAudioSilent(boolean silent) {
   1326         mDeprecatedSetAudioSilent = silent;
   1327     }
   1328 
   1329     /**
   1330      * Exposed for unit testing
   1331      * @deprecated use {@link #setProperty(String, String)} instead.
   1332      */
   1333     @Deprecated
   1334     protected void setDeprecatedSetProp(String prop) {
   1335         mDeprecatedSetProps.add(prop);
   1336     }
   1337 }
   1338