1 /*
2  * Copyright (C) 2016 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.provider.cts;
18 
19 import android.app.UiAutomation;
20 import android.os.ParcelFileDescriptor;
21 import android.util.Log;
22 
23 import androidx.test.InstrumentationRegistry;
24 
25 import java.io.BufferedReader;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.nio.charset.StandardCharsets;
31 import java.util.Objects;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 
35 /**
36  * Utility methods for provider cts tests.
37  */
38 public class ProviderTestUtils {
39     static final String TAG = "ProviderTestUtils";
40 
41     private static final int BACKUP_TIMEOUT_MILLIS = 4000;
42     private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
43             "^Backup Manager currently (enabled|disabled)$");
44 
setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)45     static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
46             throws Exception {
47         String mode = setToSmsApp ? "allow" : "default";
48         String cmd = "appops set %s %s %s";
49         executeShellCommand(String.format(cmd, packageName, "WRITE_SMS", mode), uiAutomation);
50         executeShellCommand(String.format(cmd, packageName, "READ_SMS", mode), uiAutomation);
51     }
52 
executeShellCommand(String command)53     public static String executeShellCommand(String command) throws IOException {
54         return executeShellCommand(command,
55                 InstrumentationRegistry.getInstrumentation().getUiAutomation());
56     }
57 
executeShellCommand(String command, UiAutomation uiAutomation)58     public static String executeShellCommand(String command, UiAutomation uiAutomation)
59             throws IOException {
60         Log.v(TAG, "$ " + command);
61         ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command.toString());
62         BufferedReader br = null;
63         try (InputStream in = new FileInputStream(pfd.getFileDescriptor());) {
64             br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
65             String str = null;
66             StringBuilder out = new StringBuilder();
67             while ((str = br.readLine()) != null) {
68                 Log.v(TAG, "> " + str);
69                 out.append(str);
70             }
71             return out.toString();
72         } finally {
73             if (br != null) {
74                 br.close();
75             }
76         }
77     }
78 
setBackupTransport(String transport, UiAutomation uiAutomation)79     static String setBackupTransport(String transport, UiAutomation uiAutomation) throws Exception {
80         String output = executeShellCommand("bmgr transport " + transport, uiAutomation);
81         Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
82         Matcher matcher = pattern.matcher(output);
83         if (matcher.find()) {
84             return matcher.group(1);
85         } else {
86             throw new Exception("non-parsable output setting bmgr transport: " + output);
87         }
88     }
89 
setBackupEnabled(boolean enable, UiAutomation uiAutomation)90     static boolean setBackupEnabled(boolean enable, UiAutomation uiAutomation) throws Exception {
91         // Check to see the previous state of the backup service
92         boolean previouslyEnabled = false;
93         String output = executeShellCommand("bmgr enabled", uiAutomation);
94         Matcher matcher = BMGR_ENABLED_PATTERN.matcher(output.trim());
95         if (matcher.find()) {
96             previouslyEnabled = "enabled".equals(matcher.group(1));
97         } else {
98             throw new RuntimeException("Backup output format changed.  No longer matches"
99                     + " expected regex: " + BMGR_ENABLED_PATTERN + "\nactual: '" + output + "'");
100         }
101 
102         executeShellCommand("bmgr enable " + enable, uiAutomation);
103         return previouslyEnabled;
104     }
105 
hasBackupTransport(String transport, UiAutomation uiAutomation)106     static boolean hasBackupTransport(String transport, UiAutomation uiAutomation)
107             throws Exception {
108         String output = executeShellCommand("bmgr list transports", uiAutomation);
109         for (String t : output.split(" ")) {
110             if ("*".equals(t)) {
111                 // skip the current selection marker.
112                 continue;
113             } else if (Objects.equals(transport, t)) {
114                 return true;
115             }
116         }
117         return false;
118     }
119 
runBackup(String packageName, UiAutomation uiAutomation)120     static void runBackup(String packageName, UiAutomation uiAutomation) throws Exception {
121         executeShellCommand("bmgr backupnow " + packageName, uiAutomation);
122         Thread.sleep(BACKUP_TIMEOUT_MILLIS);
123     }
124 
runRestore(String packageName, UiAutomation uiAutomation)125     static void runRestore(String packageName, UiAutomation uiAutomation) throws Exception {
126         executeShellCommand("bmgr restore 1 " + packageName, uiAutomation);
127         Thread.sleep(BACKUP_TIMEOUT_MILLIS);
128     }
129 
wipeBackup(String backupTransport, String packageName, UiAutomation uiAutomation)130     static void wipeBackup(String backupTransport, String packageName, UiAutomation uiAutomation)
131             throws Exception {
132         executeShellCommand("bmgr wipe " + backupTransport + " " + packageName, uiAutomation);
133     }
134 
135 }
136