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 
shouldTestTelecom(Context context)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 
setDefaultDialer(Instrumentation instrumentation, String packageName)70     public static String setDefaultDialer(Instrumentation instrumentation, String packageName)
71             throws Exception {
72         return executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_DIALER + packageName);
73     }
74 
getDefaultDialer(Instrumentation instrumentation)75     public static String getDefaultDialer(Instrumentation instrumentation) throws Exception {
76         return executeShellCommand(instrumentation, COMMAND_GET_DEFAULT_DIALER);
77     }
78 
getSystemDialer(Instrumentation instrumentation)79     public static String getSystemDialer(Instrumentation instrumentation) throws Exception {
80         return executeShellCommand(instrumentation, COMMAND_GET_SYSTEM_DIALER);
81     }
82 
enablePhoneAccount(Instrumentation instrumentation, PhoneAccountHandle handle)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 
registerSimPhoneAccount(Instrumentation instrumentation, PhoneAccountHandle handle, String label, String address)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      */
executeShellCommand(Instrumentation instrumentation, String command)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 
closeQuietly(AutoCloseable closeable)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