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.build.IBuildInfo; 19 import com.android.tradefed.config.Option; 20 import com.android.tradefed.config.OptionClass; 21 import com.android.tradefed.device.DeviceNotAvailableException; 22 import com.android.tradefed.device.ITestDevice; 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(ITestDevice device, IBuildInfo buildInfo)63 public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, 64 BuildError, DeviceNotAvailableException { 65 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 = (!mExpectedSettingValues.isEmpty()) ? 83 String.format("settings get %s %s", mSettingType, mSettingName) : ""; 84 String shellCmdPut = (mSetValue != null) ? 85 String.format("settings put %s %s %s", mSettingType, mSettingName, mSetValue) : ""; 86 87 88 /* Case 1: Both expected-values and set-value are given */ 89 if (mSetValue != null && !mExpectedSettingValues.isEmpty()) { 90 // first ensure that the set-value given can be found in expected-values 91 if (!mExpectedSettingValues.contains(mSetValue)) { 92 throw new TargetSetupError(String.format( 93 "set-value for %s is %s, but value not found in expected-values: %s", 94 mSettingName, mSetValue, mExpectedSettingValues.toString()), 95 device.getDeviceDescriptor()); 96 } 97 String currentSettingValue = device.executeShellCommand(shellCmdGet).trim(); 98 // only change unexpected setting value 99 if (!mExpectedSettingValues.contains(currentSettingValue)) { 100 CLog.d("Changing value for %s from %s to %s", 101 mSettingName, currentSettingValue, mSetValue); 102 device.executeShellCommand(shellCmdPut); 103 } 104 return; 105 } 106 107 /* Case 2: Only set-value given */ 108 if (mSetValue != null) { 109 CLog.d("Setting %s to value %s", mSettingName, mSetValue); 110 device.executeShellCommand(shellCmdPut); 111 return; 112 } 113 114 /* Case 3: Only expected-values given */ 115 String currentSettingValue = device.executeShellCommand(shellCmdGet).trim(); 116 if (!mExpectedSettingValues.contains(currentSettingValue)) { 117 if (mFailureMessage == null) { 118 mFailureMessage = String.format( 119 "Device setting \"%s\" returned \"%s\", not found in %s", 120 mSettingName, currentSettingValue, mExpectedSettingValues.toString()); 121 } 122 throw new TargetSetupError(mFailureMessage, device.getDeviceDescriptor()); 123 } 124 } 125 126 } 127