1 /* 2 * Copyright (C) 2021 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 android.app.time.cts.shell; 17 18 import static org.junit.Assume.assumeTrue; 19 20 import java.io.BufferedReader; 21 import java.io.StringReader; 22 import java.util.Objects; 23 24 /** 25 * A class for interacting with the {@code location_time_zone_manager} service via the shell "cmd" 26 * command-line interface. 27 */ 28 public class LocationTimeZoneManagerShellHelper { 29 30 /** 31 * The name of the service for shell commands. 32 */ 33 private static final String SERVICE_NAME = "location_time_zone_manager"; 34 35 /** 36 * A shell command that starts the service (after stop). 37 */ 38 private static final String SHELL_COMMAND_START = "start"; 39 40 /** 41 * A shell command that stops the service. 42 */ 43 private static final String SHELL_COMMAND_STOP = "stop"; 44 45 /** 46 * A shell command that clears recorded provider state information during tests. 47 */ 48 private static final String SHELL_COMMAND_CLEAR_RECORDED_PROVIDER_STATES = 49 "clear_recorded_provider_states"; 50 51 /** 52 * A shell command that tells the service to dump its current state. 53 */ 54 private static final String SHELL_COMMAND_DUMP_STATE = "dump_state"; 55 56 /** 57 * Option for {@link #SHELL_COMMAND_DUMP_STATE} that tells it to dump state as a binary proto. 58 */ 59 private static final String DUMP_STATE_OPTION_PROTO = "proto"; 60 61 /** A shell command that starts the location_time_zone_manager with named test providers. */ 62 public static final String SHELL_COMMAND_START_WITH_TEST_PROVIDERS = 63 "start_with_test_providers"; 64 65 /** 66 * The token that can be passed to {@link #SHELL_COMMAND_START_WITH_TEST_PROVIDERS} to indicate 67 * there is no provider. 68 */ 69 public static final String NULL_PACKAGE_NAME_TOKEN = "@null"; 70 71 private static final String SHELL_CMD_PREFIX = "cmd " + SERVICE_NAME + " "; 72 73 private final DeviceShellCommandExecutor mShellCommandExecutor; 74 LocationTimeZoneManagerShellHelper(DeviceShellCommandExecutor shellCommandExecutor)75 public LocationTimeZoneManagerShellHelper(DeviceShellCommandExecutor shellCommandExecutor) { 76 mShellCommandExecutor = Objects.requireNonNull(shellCommandExecutor); 77 } 78 79 /** 80 * Throws an {@link org.junit.AssumptionViolatedException} if the location_time_zone_manager 81 * service is not found. The service can be turned off in config, so this can be used to prevent 82 * CTS tests that need it from running. 83 */ assumeLocationTimeZoneManagerIsPresent()84 public void assumeLocationTimeZoneManagerIsPresent() throws Exception { 85 assumeTrue(isLocationTimeZoneManagerPresent()); 86 } 87 88 /** 89 * Returns {@code false} if the location_time_zone_manager service is not found. 90 */ isLocationTimeZoneManagerPresent()91 public boolean isLocationTimeZoneManagerPresent() throws Exception { 92 // Look for the service name in "cmd -l". 93 String serviceList = mShellCommandExecutor.executeToString("cmd -l"); 94 try (BufferedReader reader = new BufferedReader(new StringReader(serviceList))) { 95 String serviceName; 96 while ((serviceName = reader.readLine()) != null) { 97 serviceName = serviceName.trim(); 98 if (SERVICE_NAME.equals(serviceName)) { 99 return true; 100 } 101 } 102 return false; 103 } 104 } 105 106 /** Executes "start". Starts the service. */ start()107 public void start() throws Exception { 108 mShellCommandExecutor.executeToTrimmedString(SHELL_CMD_PREFIX + SHELL_COMMAND_START); 109 } 110 111 /** Executes "stop". Stops the service. */ stop()112 public void stop() throws Exception { 113 mShellCommandExecutor.executeToTrimmedString(SHELL_CMD_PREFIX + SHELL_COMMAND_STOP); 114 } 115 116 /** Executes "clear_recorded_provider_states". */ clearRecordedProviderStates()117 public void clearRecordedProviderStates() throws Exception { 118 String cmd = SHELL_COMMAND_CLEAR_RECORDED_PROVIDER_STATES; 119 mShellCommandExecutor.executeToTrimmedString(SHELL_CMD_PREFIX + cmd); 120 } 121 122 /** 123 * Executes "dump_state". Raw proto bytes are returned as host protos tend to use "full" proto, 124 * device protos use "lite". 125 **/ dumpState()126 public byte[] dumpState() throws Exception { 127 String cmd = String.format("%s --%s", SHELL_COMMAND_DUMP_STATE, DUMP_STATE_OPTION_PROTO); 128 return mShellCommandExecutor.executeToBytes(SHELL_CMD_PREFIX + cmd); 129 } 130 131 /** Executes "start_with_test_providers". */ startWithTestProviders(String testPrimaryLocationTimeZoneProviderPackageName, String testSecondaryLocationTimeZoneProviderPackageName, boolean recordProviderStates)132 public void startWithTestProviders(String testPrimaryLocationTimeZoneProviderPackageName, 133 String testSecondaryLocationTimeZoneProviderPackageName, boolean recordProviderStates) 134 throws Exception { 135 testPrimaryLocationTimeZoneProviderPackageName = 136 replaceNullPackageNameWithToken(testPrimaryLocationTimeZoneProviderPackageName); 137 testSecondaryLocationTimeZoneProviderPackageName = 138 replaceNullPackageNameWithToken(testSecondaryLocationTimeZoneProviderPackageName); 139 String cmd = String.format("%s %s %s %s", 140 SHELL_COMMAND_START_WITH_TEST_PROVIDERS, 141 testPrimaryLocationTimeZoneProviderPackageName, 142 testSecondaryLocationTimeZoneProviderPackageName, 143 recordProviderStates); 144 mShellCommandExecutor.executeToBytes(SHELL_CMD_PREFIX + cmd); 145 } 146 replaceNullPackageNameWithToken(String packageName)147 private static String replaceNullPackageNameWithToken(String packageName) { 148 return packageName == null ? NULL_PACKAGE_NAME_TOKEN : packageName; 149 } 150 } 151