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 android.telecom.cts; 17 18 import android.app.Instrumentation; 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.pm.PackageManager; 22 import android.os.Build; 23 import android.os.ParcelFileDescriptor; 24 import android.telecom.PhoneAccountHandle; 25 26 import java.io.BufferedReader; 27 import java.io.FileInputStream; 28 import java.io.InputStream; 29 import java.io.InputStreamReader; 30 import java.nio.charset.StandardCharsets; 31 32 public class TestUtils { 33 static final String TAG = "TelecomCTSTests"; 34 static final boolean HAS_TELECOM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 35 static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000; 36 37 // Non-final to allow modification by tests not in this package (e.g. permission-related 38 // tests in the Telecom2 test package. 39 public static String PACKAGE = "com.android.cts.telecom"; 40 public static final String COMPONENT = "android.telecom.cts.CtsConnectionService"; 41 public static final String REMOTE_COMPONENT = "android.telecom.cts.CtsRemoteConnectionService"; 42 public static final String ACCOUNT_ID = "xtstest_CALL_PROVIDER_ID"; 43 public static final String REMOTE_ACCOUNT_ID = "xtstest_REMOTE_CALL_PROVIDER_ID"; 44 45 public static final String ACCOUNT_LABEL = "CTSConnectionService"; 46 public static final String REMOTE_ACCOUNT_LABEL = "CTSRemoteConnectionService"; 47 48 private static final String COMMAND_SET_DEFAULT_DIALER = "telecom set-default-dialer "; 49 50 private static final String COMMAND_GET_DEFAULT_DIALER = "telecom get-default-dialer"; 51 52 private static final String COMMAND_GET_SYSTEM_DIALER = "telecom get-system-dialer"; 53 54 private static final String COMMAND_ENABLE = "telecom set-phone-account-enabled "; 55 56 private static final String COMMAND_REGISTER_SIM = "telecom register-sim-phone-account "; 57 58 public static final String MERGE_CALLER_NAME = "calls-merged"; 59 public static final String SWAP_CALLER_NAME = "calls-swapped"; 60 61 public static boolean shouldTestTelecom(Context context) { 62 if (!HAS_TELECOM) { 63 return false; 64 } 65 final PackageManager pm = context.getPackageManager(); 66 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && 67 pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE); 68 } 69 70 public static String setDefaultDialer(Instrumentation instrumentation, String packageName) 71 throws Exception { 72 return executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_DIALER + packageName); 73 } 74 75 public static String getDefaultDialer(Instrumentation instrumentation) throws Exception { 76 return executeShellCommand(instrumentation, COMMAND_GET_DEFAULT_DIALER); 77 } 78 79 public static String getSystemDialer(Instrumentation instrumentation) throws Exception { 80 return executeShellCommand(instrumentation, COMMAND_GET_SYSTEM_DIALER); 81 } 82 83 public static void enablePhoneAccount(Instrumentation instrumentation, 84 PhoneAccountHandle handle) throws Exception { 85 final ComponentName component = handle.getComponentName(); 86 executeShellCommand(instrumentation, COMMAND_ENABLE 87 + component.getPackageName() + "/" + component.getClassName() + " " 88 + handle.getId()); 89 } 90 91 public static void registerSimPhoneAccount(Instrumentation instrumentation, 92 PhoneAccountHandle handle, String label, String address) throws Exception { 93 final ComponentName component = handle.getComponentName(); 94 executeShellCommand(instrumentation, COMMAND_REGISTER_SIM 95 + component.getPackageName() + "/" + component.getClassName() + " " 96 + handle.getId() + " " + label + " " + address); 97 } 98 99 /** 100 * Executes the given shell command and returns the output in a string. Note that even 101 * if we don't care about the output, we have to read the stream completely to make the 102 * command execute. 103 */ 104 public static String executeShellCommand(Instrumentation instrumentation, 105 String command) throws Exception { 106 final ParcelFileDescriptor pfd = 107 instrumentation.getUiAutomation().executeShellCommand(command); 108 BufferedReader br = null; 109 try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) { 110 br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); 111 String str = null; 112 StringBuilder out = new StringBuilder(); 113 while ((str = br.readLine()) != null) { 114 out.append(str); 115 } 116 return out.toString(); 117 } finally { 118 if (br != null) { 119 closeQuietly(br); 120 } 121 closeQuietly(pfd); 122 } 123 } 124 125 private static void closeQuietly(AutoCloseable closeable) { 126 if (closeable != null) { 127 try { 128 closeable.close(); 129 } catch (RuntimeException rethrown) { 130 throw rethrown; 131 } catch (Exception ignored) { 132 } 133 } 134 } 135 } 136