AutofillManagerServiceShellCommand.java revision 9f9ee25515591ef33281708c0ab911962f4364a6
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 17package com.android.server.autofill; 18 19import static com.android.server.autofill.AutofillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS; 20 21import android.os.Bundle; 22import android.os.ShellCommand; 23import android.os.UserHandle; 24import android.view.autofill.AutofillManager; 25 26import com.android.internal.os.IResultReceiver; 27 28import java.io.PrintWriter; 29import java.util.ArrayList; 30import java.util.concurrent.CountDownLatch; 31import java.util.concurrent.TimeUnit; 32 33public final class AutofillManagerServiceShellCommand extends ShellCommand { 34 35 private final AutofillManagerService mService; 36 37 public AutofillManagerServiceShellCommand(AutofillManagerService service) { 38 mService = service; 39 } 40 41 @Override 42 public int onCommand(String cmd) { 43 if (cmd == null) { 44 return handleDefaultCommands(cmd); 45 } 46 final PrintWriter pw = getOutPrintWriter(); 47 switch (cmd) { 48 case "list": 49 return requestList(pw); 50 case "destroy": 51 return requestDestroy(pw); 52 case "reset": 53 return requestReset(); 54 case "get": 55 return requestGet(pw); 56 case "set": 57 return requestSet(pw); 58 default: 59 return handleDefaultCommands(cmd); 60 } 61 } 62 63 @Override 64 public void onHelp() { 65 try (final PrintWriter pw = getOutPrintWriter();) { 66 pw.println("AutoFill Service (autofill) commands:"); 67 pw.println(" help"); 68 pw.println(" Prints this help text."); 69 pw.println(""); 70 pw.println(" get log_level "); 71 pw.println(" Gets the Autofill log level (off | debug | verbose)."); 72 pw.println(""); 73 pw.println(" set log_level [off | debug | verbose]"); 74 pw.println(" Sets the Autofill log level."); 75 pw.println(""); 76 pw.println(" list sessions [--user USER_ID]"); 77 pw.println(" List all pending sessions."); 78 pw.println(""); 79 pw.println(" destroy sessions [--user USER_ID]"); 80 pw.println(" Destroy all pending sessions."); 81 pw.println(""); 82 pw.println(" reset"); 83 pw.println(" Reset all pending sessions and cached service connections."); 84 pw.println(""); 85 } 86 } 87 88 private int requestGet(PrintWriter pw) { 89 if (!isNextArgLogLevel(pw, "get")) { 90 return -1; 91 } 92 final int logLevel = mService.getLogLevel(); 93 switch (logLevel) { 94 case AutofillManager.FLAG_ADD_CLIENT_VERBOSE: 95 pw.println("verbose"); 96 return 0; 97 case AutofillManager.FLAG_ADD_CLIENT_DEBUG: 98 pw.println("debug"); 99 return 0; 100 case 0: 101 pw.println("off"); 102 return 0; 103 default: 104 pw.println("unknow (" + logLevel + ")"); 105 return 0; 106 } 107 } 108 109 private int requestSet(PrintWriter pw) { 110 if (!isNextArgLogLevel(pw, "set")) { 111 return -1; 112 } 113 final String logLevel = getNextArg(); 114 switch (logLevel.toLowerCase()) { 115 case "verbose": 116 mService.setLogLevel(AutofillManager.FLAG_ADD_CLIENT_VERBOSE); 117 return 0; 118 case "debug": 119 mService.setLogLevel(AutofillManager.FLAG_ADD_CLIENT_DEBUG); 120 return 0; 121 case "off": 122 mService.setLogLevel(0); 123 return 0; 124 default: 125 pw.println("Invalid level: " + logLevel); 126 return -1; 127 } 128 } 129 130 private int requestDestroy(PrintWriter pw) { 131 if (!isNextArgSessions(pw)) { 132 return -1; 133 } 134 135 final int userId = getUserIdFromArgsOrAllUsers(); 136 final CountDownLatch latch = new CountDownLatch(1); 137 final IResultReceiver receiver = new IResultReceiver.Stub() { 138 @Override 139 public void send(int resultCode, Bundle resultData) { 140 latch.countDown(); 141 } 142 }; 143 return requestSessionCommon(pw, latch, () -> mService.destroySessions(userId, receiver)); 144 } 145 146 private int requestList(PrintWriter pw) { 147 if (!isNextArgSessions(pw)) { 148 return -1; 149 } 150 151 final int userId = getUserIdFromArgsOrAllUsers(); 152 final CountDownLatch latch = new CountDownLatch(1); 153 final IResultReceiver receiver = new IResultReceiver.Stub() { 154 @Override 155 public void send(int resultCode, Bundle resultData) { 156 final ArrayList<String> sessions = resultData 157 .getStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS); 158 for (String session : sessions) { 159 pw.println(session); 160 } 161 latch.countDown(); 162 } 163 }; 164 return requestSessionCommon(pw, latch, () -> mService.listSessions(userId, receiver)); 165 } 166 167 private boolean isNextArgSessions(PrintWriter pw) { 168 final String type = getNextArgRequired(); 169 if (!type.equals("sessions")) { 170 pw.println("Error: invalid list type"); 171 return false; 172 } 173 return true; 174 } 175 176 private boolean isNextArgLogLevel(PrintWriter pw, String cmd) { 177 final String type = getNextArgRequired(); 178 if (!type.equals("log_level")) { 179 pw.println("Error: invalid " + cmd + " type: " + type); 180 return false; 181 } 182 return true; 183 } 184 185 private int requestSessionCommon(PrintWriter pw, CountDownLatch latch, 186 Runnable command) { 187 command.run(); 188 189 try { 190 final boolean received = latch.await(5, TimeUnit.SECONDS); 191 if (!received) { 192 pw.println("Timed out after 5 seconds"); 193 return -1; 194 } 195 } catch (InterruptedException e) { 196 pw.println("System call interrupted"); 197 Thread.currentThread().interrupt(); 198 return -1; 199 } 200 return 0; 201 } 202 203 private int requestReset() { 204 mService.reset(); 205 return 0; 206 } 207 208 private int getUserIdFromArgsOrAllUsers() { 209 if ("--user".equals(getNextArg())) { 210 return UserHandle.parseUserArg(getNextArgRequired()); 211 } 212 return UserHandle.USER_ALL; 213 } 214} 215