import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.os.SomeArgs;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.List;
/**
private static final int MSG_UPDATE_SESSION = 2;
private static final int MSG_FINISH_SESSION = 3;
private static final int MSG_REQUEST_SAVE_FOR_USER = 4;
+ private static final int MSG_LIST_SESSIONS = 5;
+ private static final int MSG_RESET = 6;
+
+ static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
private final Context mContext;
private final AutoFillUI mUi;
final int flags = args.argi6;
handleUpdateSession(userId, activityToken, autoFillId, bounds, value, flags);
return;
+ } case MSG_LIST_SESSIONS: {
+ handleListForUser(msg.arg1, (IResultReceiver) msg.obj);
+ return;
+ } case MSG_RESET: {
+ handleReset();
+ return;
} default: {
Slog.w(TAG, "Invalid message: " + msg);
}
return service;
}
+ // Called by Shell command.
void requestSaveForUser(int userId) {
+ Slog.i(TAG, "requestSaveForUser(): " + userId);
mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageI(
MSG_REQUEST_SAVE_FOR_USER, userId));
}
+ // Called by Shell command.
+ void listSessions(int userId, IResultReceiver receiver) {
+ Slog.i(TAG, "listSessions() for userId " + userId);
+ mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ mHandlerCaller.sendMessage(
+ mHandlerCaller.obtainMessageIO(MSG_LIST_SESSIONS, userId, receiver));
+ }
+
+ // Called by Shell command.
+ void reset() {
+ Slog.i(TAG, "reset()");
+ mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_RESET));
+ }
+
/**
* Removes a cached service for a given user.
*/
}
}
+ private void handleListForUser(int userId, IResultReceiver receiver) {
+ final Bundle resultData = new Bundle();
+ final ArrayList<String> sessions = new ArrayList<>();
+
+ synchronized (mLock) {
+ if (userId != UserHandle.USER_ALL) {
+ mServicesCache.get(userId).listSessionsLocked(sessions);
+ } else {
+ final int size = mServicesCache.size();
+ for (int i = 0; i < size; i++) {
+ mServicesCache.valueAt(i).listSessionsLocked(sessions);
+ }
+ }
+ }
+
+ resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions);
+ try {
+ receiver.send(0, resultData);
+ } catch (RemoteException e) {
+ // Just ignore it...
+ }
+ }
+
+ private void handleReset() {
+ synchronized (mLock) {
+ final int size = mServicesCache.size();
+ for (int i = 0; i < size; i++) {
+ mServicesCache.valueAt(i).destroyLocked();
+ }
+ mServicesCache.clear();
+ }
+ }
+
final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
@Override
package com.android.server.autofill;
+import static com.android.server.autofill.AutoFillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
+
import android.app.ActivityManager;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.UserHandle;
+import com.android.internal.os.IResultReceiver;
+
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
public final class AutoFillManagerServiceShellCommand extends ShellCommand {
return handleDefaultCommands(cmd);
}
final PrintWriter pw = getOutPrintWriter();
- try {
- switch (cmd) {
- case "save":
- return requestSave();
- default:
- return handleDefaultCommands(cmd);
- }
- } catch (RemoteException e) {
- pw.println("error: " + e);
+ switch (cmd) {
+ case "save":
+ return requestSave();
+ case "list":
+ return requestList(pw);
+ case "reset":
+ return requestReset();
+ default:
+ return handleDefaultCommands(cmd);
}
- return -1;
}
@Override
pw.println(" help");
pw.println(" Prints this help text.");
pw.println("");
+ pw.println(" list sessions [--user USER_ID]");
+ pw.println(" List all pending sessions.");
+ pw.println("");
pw.println(" save [--user USER_ID]");
pw.println(" Request provider to save contents of the top activity. ");
pw.println("");
+ pw.println(" reset");
+ pw.println(" Reset all pending sessions and cached service connections.");
+ pw.println("");
}
}
- private int requestSave() throws RemoteException {
- final int userId = getUserIdFromArgs();
+ private int requestSave() {
+ final int userId = getUserIdFromArgsOrCurrentUser();
mService.requestSaveForUser(userId);
return 0;
}
- private int getUserIdFromArgs() {
+ private int requestList(PrintWriter pw) {
+ final String type = getNextArgRequired();
+ if (!type.equals("sessions")) {
+ pw.println("Error: invalid list type");
+ return -1;
+
+ }
+ final int userId = getUserIdFromArgsOrAllUsers();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final IResultReceiver receiver = new IResultReceiver.Stub() {
+
+ @Override
+ public void send(int resultCode, Bundle resultData) throws RemoteException {
+ final ArrayList<String> sessions = resultData
+ .getStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS);
+
+ for (String session : sessions) {
+ pw.println(session);
+ }
+ latch.countDown();
+ }
+ };
+
+ mService.listSessions(userId, receiver);
+
+ try {
+ final boolean received = latch.await(5, TimeUnit.SECONDS);
+ if (!received) {
+ pw.println("Timed out after 5 seconds");
+ return -1;
+ }
+ } catch (InterruptedException e) {
+ pw.println("System call interrupted");
+ Thread.currentThread().interrupt();
+ return -1;
+ }
+ return 0;
+ }
+
+ private int requestReset() {
+ mService.reset();
+ return 0;
+ }
+
+ private int getUserIdFromArgsOrCurrentUser() {
if ("--user".equals(getNextArg())) {
return UserHandle.parseUserArg(getNextArgRequired());
}
return ActivityManager.getCurrentUser();
}
+
+ private int getUserIdFromArgsOrAllUsers() {
+ if ("--user".equals(getNextArg())) {
+ return UserHandle.parseUserArg(getNextArgRequired());
+ }
+ return UserHandle.USER_ALL;
+ }
}