• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 android.telecom.cts.apps;
18 
19 import android.app.Instrumentation;
20 import android.content.ComponentName;
21 import android.os.ParcelFileDescriptor;
22 import android.os.UserHandle;
23 import android.os.UserManager;
24 import android.telecom.PhoneAccountHandle;
25 import android.util.Log;
26 
27 import java.io.BufferedReader;
28 import java.io.FileInputStream;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.nio.charset.StandardCharsets;
32 
33 /**
34  * This class should be used in Telecom CTS test classes to statically execute shell commands.
35  */
36 public class ShellCommandExecutor {
37     private static final String sTAG = ShellCommandExecutor.class.getSimpleName();
38     public static final String COMMAND_RESET_CAR = "cmd telecom cleanup";
39     public static final String COMMAND_GET_DEFAULT_DIALER = "cmd telecom get-default-dialer";
40     public static final String COMMAND_SET_DEFAULT_DIALER = "cmd telecom set-default-dialer ";
41     public static final String COMMAND_ENABLE = "cmd telecom set-phone-account-enabled ";
42     public static final String COMMAND_CLEANUP_STUCK_CALLS = "cmd telecom cleanup-stuck-calls";
43     public static final String COMMAND_SET_DEFAULT_PHONE_ACCOUNT =
44             "cmd telecom set-user-selected-outgoing-phone-account ";
45     public static final String COMMAND_DUMP_TELECOM = "dumpsys telecom";
46     public static final String COMMAND_WAIT_FOR_AUDIO_OPS_COMPLETE =
47             "cmd telecom wait-for-audio-ops-complete";
48     public static final String COMMAND_WAIT_FOR_AUDIO_ACTIVE = "cmd telecom wait-for-audio-active";
49 
50     /** Emergency call related setup constants */
51     private static final String COMMAND_SET_SYSTEM_DIALER = "telecom set-system-dialer ";
52 
53     private static final String INCALL_COMPONENT =
54             "com.google.android.dialer" + "/com.android.incallui.InCallServiceImpl";
55     private static final String COMMAND_ADD_TEST_EMERGENCY_NUMBER =
56             "cmd phone emergency-number-test-mode -a ";
57     private static final String COMMAND_CLEAR_TEST_EMERGENCY_NUMBERS =
58             "cmd phone emergency-number-test-mode -c";
59     private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_NAME_FILTER =
60             "telecom set-test-emergency-phone-account-package-filter ";
61     private static final String COMMAND_REGISTER_SIM = "telecom register-sim-phone-account ";
62 
63     /**
64      * Executes the given shell command and returns the output in a string. Note that even
65      * if we don't care about the output, we have to read the stream completely to make the
66      * command execute.
67      */
executeShellCommand(Instrumentation instrumentation, String command)68     public static String executeShellCommand(Instrumentation instrumentation,
69             String command) throws Exception {
70         final ParcelFileDescriptor pfd =
71                 instrumentation.getUiAutomation().executeShellCommand(command);
72         BufferedReader br = null;
73         try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
74             br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
75             String str = null;
76             StringBuilder out = new StringBuilder();
77             while ((str = br.readLine()) != null) {
78                 out.append(str);
79             }
80             return out.toString();
81         } finally {
82             if (br != null) {
83                 closeQuietly(br);
84             }
85             closeQuietly(pfd);
86         }
87     }
88 
closeQuietly(AutoCloseable closeable)89     private static void closeQuietly(AutoCloseable closeable) {
90         if (closeable != null) {
91             try {
92                 closeable.close();
93             } catch (RuntimeException rethrown) {
94                 throw rethrown;
95             } catch (Exception ignored) {
96                 Log.w(sTAG, "closeQuietly: exception thrown: e=" + ignored);
97             }
98         }
99     }
100 
dumpTelecom(Instrumentation instrumentation)101     public static void dumpTelecom(Instrumentation instrumentation) throws Exception {
102         executeShellCommand(instrumentation, COMMAND_DUMP_TELECOM);
103     }
104 
setDefaultDialer(Instrumentation instrumentation, String packageName)105     public static String setDefaultDialer(Instrumentation instrumentation, String packageName)
106             throws Exception {
107         return executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_DIALER + packageName);
108     }
109 
getDefaultDialer(Instrumentation instrumentation)110     public static String getDefaultDialer(Instrumentation instrumentation) throws Exception {
111         return executeShellCommand(instrumentation, COMMAND_GET_DEFAULT_DIALER);
112     }
113 
getSystemDialer(Instrumentation instrumentation)114     public static String getSystemDialer(Instrumentation instrumentation) throws Exception {
115         return executeShellCommand(instrumentation, "telecom get-system-dialer");
116     }
117 
setSystemDialerOverride( Instrumentation instrumentation, String packageName)118     public static String setSystemDialerOverride(
119             Instrumentation instrumentation, String packageName) throws Exception {
120         return executeShellCommand(instrumentation, COMMAND_SET_SYSTEM_DIALER + packageName);
121     }
122 
clearSystemDialerOverride(Instrumentation instrumentation)123     public static String clearSystemDialerOverride(Instrumentation instrumentation)
124             throws Exception {
125         return executeShellCommand(instrumentation, COMMAND_SET_SYSTEM_DIALER + "default");
126     }
127 
addTestEmergencyNumber(Instrumentation instr, String testNumber)128     public static void addTestEmergencyNumber(Instrumentation instr, String testNumber)
129             throws Exception {
130         executeShellCommand(instr, COMMAND_ADD_TEST_EMERGENCY_NUMBER + testNumber);
131     }
132 
clearTestEmergencyNumbers(Instrumentation instr)133     public static void clearTestEmergencyNumbers(Instrumentation instr) throws Exception {
134         executeShellCommand(instr, COMMAND_CLEAR_TEST_EMERGENCY_NUMBERS);
135     }
136 
registerEmergencyPhoneAccount( Instrumentation instrumentation, PhoneAccountHandle handle, String label, String address)137     public static void registerEmergencyPhoneAccount(
138             Instrumentation instrumentation,
139             PhoneAccountHandle handle,
140             String label,
141             String address)
142             throws Exception {
143         final ComponentName component = handle.getComponentName();
144         final long currentUserSerial = getUserSerialNumber(instrumentation, handle.getUserHandle());
145         executeShellCommand(
146                 instrumentation,
147                 COMMAND_REGISTER_SIM
148                         + "-e "
149                         + component.getPackageName()
150                         + "/"
151                         + component.getClassName()
152                         + " "
153                         + handle.getId()
154                         + " "
155                         + currentUserSerial
156                         + " "
157                         + label
158                         + " "
159                         + address);
160     }
161 
setTestEmergencyPhoneAccountPackageFilter( Instrumentation instr, String packageName)162     public static void setTestEmergencyPhoneAccountPackageFilter(
163             Instrumentation instr, String packageName) throws Exception {
164         executeShellCommand(
165                 instr, COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_NAME_FILTER + packageName);
166     }
167 
clearTestEmergencyPhoneAccountPackageFilter(Instrumentation instr)168     public static void clearTestEmergencyPhoneAccountPackageFilter(Instrumentation instr)
169             throws Exception {
170         executeShellCommand(instr, COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_NAME_FILTER);
171     }
172 
enablePhoneAccount(Instrumentation instrumentation, PhoneAccountHandle handle)173     public static void enablePhoneAccount(Instrumentation instrumentation,
174             PhoneAccountHandle handle) throws Exception {
175         final ComponentName component = handle.getComponentName();
176         final long userSerial = getUserSerialNumber(instrumentation, handle.getUserHandle());
177         executeShellCommand(instrumentation, COMMAND_ENABLE
178                 + component.getPackageName() + "/" + component.getClassName() + " "
179                 + handle.getId() + " " + userSerial);
180     }
181 
getUserSerialNumber(Instrumentation instrumentation, UserHandle handle)182     private static long getUserSerialNumber(Instrumentation instrumentation, UserHandle handle) {
183         UserManager userManager =
184                 instrumentation.getContext().getSystemService(UserManager.class);
185         return userManager.getSerialNumberForUser(handle);
186     }
187 }
188