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