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