From: Felipe Leme Date: Thu, 9 Feb 2017 17:40:15 +0000 (-0800) Subject: Add Shell commands to list and reset auto-fill sessions. X-Git-Tag: android-x86-8.1-r1~3961^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=69a1cae41110f080f2e91dafa2f99947f2886b7a;p=android-x86%2Fframeworks-base.git Add Shell commands to list and reset auto-fill sessions. These commands are useful during development and CTS tests (for example, the test can assert there is no dangling session after it's finished). BUG: 33802548 Test: manual verification Change-Id: I61f96e30d07642fa2165df9b982c6bf32a4e8716 --- diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java index 631fb530f2d6..c16a51c8dfbd 100644 --- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java @@ -34,6 +34,7 @@ import android.database.ContentObserver; 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; @@ -54,12 +55,14 @@ import android.view.autofill.AutoFillValue; 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; /** @@ -77,6 +80,10 @@ public final class AutoFillManagerService extends SystemService { 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; @@ -111,6 +118,12 @@ public final class AutoFillManagerService extends SystemService { 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); } @@ -203,12 +216,29 @@ public final class AutoFillManagerService extends SystemService { 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. */ @@ -279,6 +309,39 @@ public final class AutoFillManagerService extends SystemService { } } + private void handleListForUser(int userId, IResultReceiver receiver) { + final Bundle resultData = new Bundle(); + final ArrayList 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 diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java index 9e0b31a76a6e..2891518c3eac 100644 --- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java @@ -70,6 +70,7 @@ import com.android.internal.os.IResultReceiver; import com.android.server.FgThread; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Map; import java.util.Map.Entry; @@ -330,6 +331,12 @@ final class AutoFillManagerServiceImpl { } } + void listSessionsLocked(ArrayList output) { + for (IBinder activityToken : mSessions.keySet()) { + output.add(mComponentName + ":" + activityToken); + } + } + @Override public String toString() { return "AutoFillManagerServiceImpl: [userId=" + mUserId diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java index 3318b2bf3843..cfa4a1d0a107 100644 --- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java @@ -16,12 +16,20 @@ 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 { @@ -37,17 +45,16 @@ 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 @@ -57,22 +64,79 @@ public final class AutoFillManagerServiceShellCommand extends ShellCommand { 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 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; + } }