diff options
5 files changed, 52 insertions, 1 deletions
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index 2281fb6d5cc2..b9b9a18e361d 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -19,6 +19,7 @@ package android.os; import android.util.ArrayMap; import android.util.Slog; +import java.io.PrintWriter; import java.util.function.Consumer; /** @@ -399,6 +400,13 @@ public class RemoteCallbackList<E extends IInterface> { } } + /** @hide */ + public void dump(PrintWriter pw, String prefix) { + pw.print(prefix); pw.print("callbacks: "); pw.println(mCallbacks.size()); + pw.print(prefix); pw.print("killed: "); pw.println(mKilled); + pw.print(prefix); pw.print("broadcasts count: "); pw.println(mBroadcastCount); + } + private void logExcessiveCallbacks() { final long size = mCallbacks.size(); final long TOO_MANY = 3000; diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 3fcbf10df5ed..03bd4edfc863 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -53,6 +53,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +// TODO: use java.lang.ref.Cleaner once Android supports Java 9 +import sun.misc.Cleaner; + /** * The {@link AutofillManager} provides ways for apps and custom views to integrate with the * Autofill Framework lifecycle. @@ -286,6 +289,9 @@ public final class AutofillManager { private IAutoFillManagerClient mServiceClient; @GuardedBy("mLock") + private Cleaner mServiceClientCleaner; + + @GuardedBy("mLock") private AutofillCallback mCallback; private final Context mContext; @@ -1080,10 +1086,19 @@ public final class AutofillManager { if (mServiceClient == null) { mServiceClient = new AutofillManagerClient(this); try { - final int flags = mService.addClient(mServiceClient, mContext.getUserId()); + final int userId = mContext.getUserId(); + final int flags = mService.addClient(mServiceClient, userId); mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0; sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0; sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0; + final IAutoFillManager service = mService; + final IAutoFillManagerClient serviceClient = mServiceClient; + mServiceClientCleaner = Cleaner.create(this, () -> { + try { + service.removeClient(serviceClient, userId); + } catch (RemoteException e) { + } + }); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1190,6 +1205,10 @@ public final class AutofillManager { if (resetClient) { // Reset connection to system mServiceClient = null; + if (mServiceClientCleaner != null) { + mServiceClientCleaner.clean(); + mServiceClientCleaner = null; + } } } } diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl index 6bd9bec368c8..5e53896b7ab6 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -32,6 +32,7 @@ import android.view.autofill.IAutoFillManagerClient; interface IAutoFillManager { // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE int addClient(in IAutoFillManagerClient client, int userId); + void removeClient(in IAutoFillManagerClient client, int userId); int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, String packageName); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 1f4161ac54d4..d2c7f5a02fdf 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -513,6 +513,16 @@ public final class AutofillManagerService extends SystemService { } @Override + public void removeClient(IAutoFillManagerClient client, int userId) { + synchronized (mLock) { + final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); + if (service != null) { + service.removeClientLocked(client); + } + } + } + + @Override public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId, int userId) { synchronized (mLock) { diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 3a3b5707fc6f..993c65b8567c 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -254,6 +254,12 @@ final class AutofillManagerServiceImpl { return isEnabled(); } + void removeClientLocked(IAutoFillManagerClient client) { + if (mClients != null) { + mClients.unregister(client); + } + } + void setAuthenticationResultLocked(Bundle data, int sessionId, int authenticationId, int uid) { if (!isEnabled()) { return; @@ -505,6 +511,10 @@ final class AutofillManagerServiceImpl { } sendStateToClients(true); + if (mClients != null) { + mClients.kill(); + mClients = null; + } } @NonNull @@ -638,6 +648,9 @@ final class AutofillManagerServiceImpl { } } + pw.print(prefix); pw.println("Clients"); + mClients.dump(pw, prefix2); + if (mEventHistory == null || mEventHistory.getEvents() == null || mEventHistory.getEvents().size() == 0) { pw.print(prefix); pw.println("No event on last fill response"); |