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 
17 package android.accessibility.cts.common;
18 
19 import android.app.Instrumentation;
20 import android.app.UiAutomation;
21 import android.os.ParcelFileDescriptor;
22 import android.util.Log;
23 
24 import java.io.BufferedReader;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.nio.charset.StandardCharsets;
30 import java.util.LinkedList;
31 
32 /**
33  * A helper class to execute batch of shell commands.
34  */
35 public class ShellCommandBuilder {
36     private static final String LOG_TAG = "ShellCommandBuilder";
37 
38     private final LinkedList<Runnable> mCommands = new LinkedList<>();
39     private final UiAutomation mUiAutomation;
40 
41     /**
42      * Returns a {@link ShellCommandBuilder} with an {@link UiAutomation} which doesn't suppress
43      * accessibility service.
44      */
create(Instrumentation instrumentation)45     public static ShellCommandBuilder create(Instrumentation instrumentation) {
46         return new ShellCommandBuilder(instrumentation.getUiAutomation(
47                 UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES));
48     }
49 
50     /**
51      * Returns a {@link ShellCommandBuilder} with {@code uiAutomation}.
52      */
create(UiAutomation uiAutomation)53     public static ShellCommandBuilder create(UiAutomation uiAutomation) {
54         return new ShellCommandBuilder(uiAutomation);
55     }
56 
ShellCommandBuilder(UiAutomation uiAutomation)57     private ShellCommandBuilder(UiAutomation uiAutomation) {
58         mUiAutomation = uiAutomation;
59     }
60 
run()61     public void run() {
62         for (Runnable command : mCommands) {
63             command.run();
64         }
65     }
66 
deleteSecureSetting(String name)67     public ShellCommandBuilder deleteSecureSetting(String name) {
68         addCommand("settings delete secure " + name);
69         return this;
70     }
71 
putSecureSetting(String name, String value)72     public ShellCommandBuilder putSecureSetting(String name, String value) {
73         addCommand("settings put secure " + name + " " + value);
74         return this;
75     }
76 
grantPermission(String packageName, String permission)77     public ShellCommandBuilder grantPermission(String packageName, String permission) {
78         mCommands.add(() -> {
79             mUiAutomation.grantRuntimePermission(packageName, permission);
80         });
81         return this;
82     }
83 
addCommand(String command)84     public ShellCommandBuilder addCommand(String command) {
85         mCommands.add(() -> {
86             execShellCommand(mUiAutomation, command);
87         });
88         return this;
89     }
90 
execShellCommand(UiAutomation automation, String command)91     public static void execShellCommand(UiAutomation automation, String command) {
92         Log.i(LOG_TAG, "command [" + command + "]");
93         try (ParcelFileDescriptor fd = automation.executeShellCommand(command)) {
94             try (InputStream inputStream = new FileInputStream(fd.getFileDescriptor())) {
95                 try (BufferedReader reader = new BufferedReader(
96                         new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
97                     while (reader.readLine() != null) {
98                         // Keep reading.
99                     }
100                 }
101             }
102         } catch (IOException e) {
103             throw new RuntimeException("Failed to exec shell command [" + command + "]", e);
104         }
105     }
106 }
107