1 /* 2 * Copyright (C) 2015 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 package com.android.compatibility.common.tradefed.targetprep; 17 18 import com.android.tradefed.config.Option; 19 import com.android.tradefed.config.OptionClass; 20 import com.android.tradefed.device.DeviceNotAvailableException; 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.invoker.TestInformation; 23 import com.android.tradefed.log.LogUtil.CLog; 24 import com.android.tradefed.targetprep.BuildError; 25 import com.android.tradefed.targetprep.TargetSetupError; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * Checks that a given setting on the device is one of the given values 32 */ 33 @OptionClass(alias="settings-preparer") 34 public class SettingsPreparer extends PreconditionPreparer { 35 36 public enum SettingType { 37 SECURE, 38 GLOBAL, 39 SYSTEM; 40 } 41 42 /* This option must be defined, but is not explicitly marked mandatory, as subclasses of 43 * the SettingsPreparer class can define mSettingName at runtime */ 44 @Option(name = "device-setting", description = "The setting on the device to be checked") 45 protected String mSettingName = null; 46 47 /* This option must be defined, but is not explicitly marked mandatory, as subclasses of 48 * the SettingsPreparer class can define mSettingType at runtime */ 49 @Option(name = "setting-type", 50 description = "If the setting is 'secure', 'global', or 'system'") 51 protected SettingType mSettingType = null; 52 53 @Option(name = "set-value", description = "The value to be set for the setting") 54 protected String mSetValue = null; 55 56 @Option(name = "expected-values", description = "The set of expected values of the setting") 57 protected List<String> mExpectedSettingValues = new ArrayList<String>(); 58 59 @Option(name = "failure-message", description = "The text printed for an unexpected value") 60 protected String mFailureMessage = null; 61 62 @Override run(TestInformation testInfo)63 public void run(TestInformation testInfo) 64 throws TargetSetupError, BuildError, DeviceNotAvailableException { 65 ITestDevice device = testInfo.getDevice(); 66 if (mSettingName == null) { 67 throw new TargetSetupError("The \"device-setting\" option must be defined for the " + 68 "SettingsPreparer class", device.getDeviceDescriptor()); 69 } 70 71 if (mSettingType == null) { 72 throw new TargetSetupError("The \"setting-type\" option must be defined for the " + 73 "SettingsPreparer class", device.getDeviceDescriptor()); 74 } 75 76 /* At least one of the options "set-value" and "expected-values" must be set */ 77 if (mSetValue == null && mExpectedSettingValues.isEmpty()) { 78 throw new TargetSetupError("At least one of the options \"set-value\" and " + 79 "\"expected-values\" must be set", device.getDeviceDescriptor()); 80 } 81 82 String shellCmdGet = 83 !mExpectedSettingValues.isEmpty() 84 ? String.format("settings get %s %s", mSettingType, mSettingName) 85 : ""; 86 String shellCmdPut = (mSetValue != null) ? 87 String.format("settings put %s %s %s", mSettingType, mSettingName, mSetValue) : ""; 88 89 90 /* Case 1: Both expected-values and set-value are given */ 91 if (mSetValue != null && !mExpectedSettingValues.isEmpty()) { 92 // first ensure that the set-value given can be found in expected-values 93 if (!mExpectedSettingValues.contains(mSetValue)) { 94 throw new TargetSetupError(String.format( 95 "set-value for %s is %s, but value not found in expected-values: %s", 96 mSettingName, mSetValue, mExpectedSettingValues.toString()), 97 device.getDeviceDescriptor()); 98 } 99 String currentSettingValue = device.executeShellCommand(shellCmdGet).trim(); 100 // only change unexpected setting value 101 if (!mExpectedSettingValues.contains(currentSettingValue)) { 102 CLog.d("Changing value for %s from %s to %s", 103 mSettingName, currentSettingValue, mSetValue); 104 device.executeShellCommand(shellCmdPut); 105 } 106 return; 107 } 108 109 /* Case 2: Only set-value given */ 110 if (mSetValue != null) { 111 CLog.d("Setting %s to value %s", mSettingName, mSetValue); 112 device.executeShellCommand(shellCmdPut); 113 return; 114 } 115 116 /* Case 3: Only expected-values given */ 117 String currentSettingValue = device.executeShellCommand(shellCmdGet).trim(); 118 if (!mExpectedSettingValues.contains(currentSettingValue)) { 119 if (mFailureMessage == null) { 120 mFailureMessage = String.format( 121 "Device setting \"%s\" returned \"%s\", not found in %s", 122 mSettingName, currentSettingValue, mExpectedSettingValues.toString()); 123 } 124 throw new TargetSetupError(mFailureMessage, device.getDeviceDescriptor()); 125 } 126 } 127 128 } 129