diff options
8 files changed, 113 insertions, 35 deletions
diff --git a/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl b/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl index bf0bb9e2a41f..7cd372fe97d8 100644 --- a/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl +++ b/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl @@ -29,6 +29,12 @@ import android.service.autofill.InlinePresentation; oneway interface IInlineSuggestionRenderService { void renderSuggestion(in IInlineSuggestionUiCallback callback, in InlinePresentation presentation, int width, int height, - in IBinder hostInputToken, int displayId); + in IBinder hostInputToken, int displayId, int userId, int sessionId); void getInlineSuggestionsRendererInfo(in RemoteCallback callback); + + /** + * Releases the inline suggestion SurfaceControlViewHosts hosted in the service, for the + * provided userId and sessionId. + */ + void destroySuggestionViews(int userId, int sessionId); } diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java index 8790fb2299f5..839caff5c3d4 100644 --- a/core/java/android/service/autofill/InlineSuggestionRenderService.java +++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java @@ -41,6 +41,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.lang.ref.WeakReference; /** @@ -82,7 +84,7 @@ public abstract class InlineSuggestionRenderService extends Service { Boolean newValue) { if (evicted) { Log.w(TAG, - "Hit max=100 entries in the cache. Releasing oldest one to make " + "Hit max=30 entries in the cache. Releasing oldest one to make " + "space."); key.releaseSurfaceControlViewHost(); } @@ -130,7 +132,7 @@ public abstract class InlineSuggestionRenderService extends Service { private void handleRenderSuggestion(IInlineSuggestionUiCallback callback, InlinePresentation presentation, int width, int height, IBinder hostInputToken, - int displayId) { + int displayId, int userId, int sessionId) { if (hostInputToken == null) { try { callback.onError(); @@ -192,7 +194,8 @@ public abstract class InlineSuggestionRenderService extends Service { } return true; }); - final InlineSuggestionUiImpl uiImpl = new InlineSuggestionUiImpl(host, mMainHandler); + final InlineSuggestionUiImpl uiImpl = new InlineSuggestionUiImpl(host, mMainHandler, + userId, sessionId); mActiveInlineSuggestions.put(uiImpl, true); // We post the callback invocation to the end of the main thread handler queue, to make @@ -218,6 +221,18 @@ public abstract class InlineSuggestionRenderService extends Service { callback.sendResult(rendererInfo); } + private void handleDestroySuggestionViews(int userId, int sessionId) { + Log.v(TAG, "handleDestroySuggestionViews called for " + userId + ":" + sessionId); + for (final InlineSuggestionUiImpl inlineSuggestionUi : + mActiveInlineSuggestions.snapshot().keySet()) { + if (inlineSuggestionUi.mUserId == userId + && inlineSuggestionUi.mSessionId == sessionId) { + Log.v(TAG, "Destroy " + inlineSuggestionUi); + inlineSuggestionUi.releaseSurfaceControlViewHost(); + } + } + } + /** * A wrapper class around the {@link InlineSuggestionUiImpl} to ensure it's not strongly * reference by the remote system server process. @@ -260,10 +275,15 @@ public abstract class InlineSuggestionRenderService extends Service { private SurfaceControlViewHost mViewHost; @NonNull private final Handler mHandler; + private final int mUserId; + private final int mSessionId; - InlineSuggestionUiImpl(SurfaceControlViewHost viewHost, Handler handler) { + InlineSuggestionUiImpl(SurfaceControlViewHost viewHost, Handler handler, int userId, + int sessionId) { this.mViewHost = viewHost; this.mHandler = handler; + this.mUserId = userId; + this.mSessionId = sessionId; } /** @@ -302,6 +322,16 @@ public abstract class InlineSuggestionRenderService extends Service { } } + /** @hide */ + @Override + protected final void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, + @NonNull String[] args) { + pw.println("mActiveInlineSuggestions: " + mActiveInlineSuggestions.size()); + for (InlineSuggestionUiImpl impl : mActiveInlineSuggestions.snapshot().keySet()) { + pw.printf("ui: [%s] - [%d] [%d]\n", impl, impl.mUserId, impl.mSessionId); + } + } + @Override @Nullable public final IBinder onBind(@NonNull Intent intent) { @@ -311,11 +341,12 @@ public abstract class InlineSuggestionRenderService extends Service { @Override public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback, @NonNull InlinePresentation presentation, int width, int height, - @Nullable IBinder hostInputToken, int displayId) { + @Nullable IBinder hostInputToken, int displayId, int userId, + int sessionId) { mMainHandler.sendMessage( obtainMessage(InlineSuggestionRenderService::handleRenderSuggestion, InlineSuggestionRenderService.this, callback, presentation, - width, height, hostInputToken, displayId)); + width, height, hostInputToken, displayId, userId, sessionId)); } @Override @@ -324,6 +355,12 @@ public abstract class InlineSuggestionRenderService extends Service { InlineSuggestionRenderService::handleGetInlineSuggestionsRendererInfo, InlineSuggestionRenderService.this, callback)); } + @Override + public void destroySuggestionViews(int userId, int sessionId) { + mMainHandler.sendMessage(obtainMessage( + InlineSuggestionRenderService::handleDestroySuggestionViews, + InlineSuggestionRenderService.this, userId, sessionId)); + } }.asBinder(); } diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java index 11f901538868..533bbe68e274 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java @@ -149,7 +149,7 @@ final class RemoteAugmentedAutofillService @Nullable InlineSuggestionsRequest inlineSuggestionsRequest, @Nullable Function<InlineFillUi, Boolean> inlineSuggestionsCallback, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, int userId) { long requestTime = SystemClock.elapsedRealtime(); AtomicReference<ICancellationSignal> cancellationRef = new AtomicReference<>(); @@ -173,7 +173,7 @@ final class RemoteAugmentedAutofillService inlineSuggestionsRequest, inlineSuggestionsData, clientState, focusedId, focusedValue, inlineSuggestionsCallback, - client, onErrorCallback, remoteRenderService); + client, onErrorCallback, remoteRenderService, userId); if (!showingFillWindow) { requestAutofill.complete(null); } @@ -243,7 +243,8 @@ final class RemoteAugmentedAutofillService @NonNull AutofillId focusedId, @Nullable AutofillValue focusedValue, @Nullable Function<InlineFillUi, Boolean> inlineSuggestionsCallback, @NonNull IAutoFillManagerClient client, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId) { if (inlineSuggestionsData == null || inlineSuggestionsData.isEmpty() || inlineSuggestionsCallback == null || request == null || remoteRenderService == null) { @@ -312,7 +313,7 @@ final class RemoteAugmentedAutofillService Slog.w(TAG, "RemoteException starting intent sender"); } } - }, onErrorCallback, remoteRenderService); + }, onErrorCallback, remoteRenderService, userId, sessionId); if (inlineSuggestionsCallback.apply(inlineFillUi)) { mCallbacks.logAugmentedAutofillShown(sessionId, clientState); diff --git a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java index 617c111c6c38..80b8583759e7 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java @@ -88,9 +88,9 @@ public final class RemoteInlineSuggestionRenderService extends */ public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback, @NonNull InlinePresentation presentation, int width, int height, - @Nullable IBinder hostInputToken, int displayId) { + @Nullable IBinder hostInputToken, int displayId, int userId, int sessionId) { scheduleAsyncRequest((s) -> s.renderSuggestion(callback, presentation, width, height, - hostInputToken, displayId)); + hostInputToken, displayId, userId, sessionId)); } /** @@ -100,6 +100,13 @@ public final class RemoteInlineSuggestionRenderService extends scheduleAsyncRequest((s) -> s.getInlineSuggestionsRendererInfo(callback)); } + /** + * Destroys the remote inline suggestion views associated with the given user id and session id. + */ + public void destroySuggestionViews(int userId, int sessionId) { + scheduleAsyncRequest((s) -> s.destroySuggestionViews(userId, sessionId)); + } + @Nullable private static ServiceInfo getServiceInfo(Context context, int userId) { final String packageName = diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 2b9ce2f07c70..9b3d075e3f2c 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -155,6 +155,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ public final int id; + /** userId the session belongs to */ + public final int userId; + /** uid the session is for */ public final int uid; @@ -823,6 +826,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } id = sessionId; mFlags = flags; + this.userId = userId; this.taskId = taskId; this.uid = uid; mStartTime = SystemClock.elapsedRealtime(); @@ -2986,7 +2990,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mInlineSessionController.setInlineFillUiLocked( InlineFillUi.emptyUi(focusedId)); } - }, remoteRenderService); + }, remoteRenderService, userId, id); return mInlineSessionController.setInlineFillUiLocked(inlineFillUi); } @@ -3296,7 +3300,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mInlineSessionController.setInlineFillUiLocked( InlineFillUi.emptyUi(mCurrentViewId)); } - }, mService.getRemoteInlineSuggestionRenderServiceLocked()); + }, mService.getRemoteInlineSuggestionRenderServiceLocked(), userId); } }; @@ -3796,6 +3800,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mCurrentViewId != null) { mInlineSessionController.destroyLocked(mCurrentViewId); } + final RemoteInlineSuggestionRenderService remoteRenderService = + mService.getRemoteInlineSuggestionRenderServiceLocked(); + if (remoteRenderService != null) { + remoteRenderService.destroySuggestionViews(userId, id); + } + mDestroyed = true; // Log metrics diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java index 627c0733b078..25e9d5c90764 100644 --- a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java @@ -105,19 +105,20 @@ public final class InlineFillUi { @NonNull AutofillId focusedViewId, @Nullable String filterText, @NonNull AutoFillUI.AutoFillUiCallback uiCallback, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId) { if (InlineSuggestionFactory.responseNeedAuthentication(response)) { InlineSuggestion inlineAuthentication = InlineSuggestionFactory.createInlineAuthentication(request, response, - focusedViewId, uiCallback, onErrorCallback, remoteRenderService); + uiCallback, onErrorCallback, remoteRenderService, userId, sessionId); return new InlineFillUi(focusedViewId, inlineAuthentication, filterText); } else if (response.getDatasets() != null) { SparseArray<Pair<Dataset, InlineSuggestion>> inlineSuggestions = InlineSuggestionFactory.createAutofillInlineSuggestions(request, response.getRequestId(), response.getDatasets(), focusedViewId, uiCallback, onErrorCallback, - remoteRenderService); + remoteRenderService, userId, sessionId); return new InlineFillUi(focusedViewId, inlineSuggestions, filterText); } return new InlineFillUi(focusedViewId, new SparseArray<>(), filterText); @@ -132,11 +133,12 @@ public final class InlineFillUi { @NonNull AutofillId focusedViewId, @Nullable String filterText, @NonNull InlineSuggestionUiCallback uiCallback, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId) { SparseArray<Pair<Dataset, InlineSuggestion>> inlineSuggestions = InlineSuggestionFactory.createAugmentedAutofillInlineSuggestions(request, datasets, focusedViewId, - uiCallback, onErrorCallback, remoteRenderService); + uiCallback, onErrorCallback, remoteRenderService, userId, sessionId); return new InlineFillUi(focusedViewId, inlineSuggestions, filterText); } diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java index 462ffd668e2e..8fcb8aa9393c 100644 --- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java +++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java @@ -53,9 +53,9 @@ final class InlineSuggestionFactory { public static InlineSuggestion createInlineAuthentication( @NonNull InlineSuggestionsRequest request, @NonNull FillResponse response, - @NonNull AutofillId autofillId, @NonNull AutoFillUI.AutoFillUiCallback client, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, int userId, + int sessionId) { final BiConsumer<Dataset, Integer> onClickFactory = (dataset, datasetIndex) -> { client.authenticate(response.getRequestId(), datasetIndex, response.getAuthentication(), response.getClientState(), @@ -66,7 +66,8 @@ final class InlineSuggestionFactory { InlinePresentation inlineAuthentication = response.getInlinePresentation(); return createInlineAuthSuggestion( mergedInlinePresentation(request, 0, inlineAuthentication), - remoteRenderService, onClickFactory, onErrorCallback, intentSenderConsumer, + remoteRenderService, userId, sessionId, + onClickFactory, onErrorCallback, intentSenderConsumer, request.getHostInputToken(), request.getHostDisplayId()); } @@ -80,7 +81,8 @@ final class InlineSuggestionFactory { @NonNull List<Dataset> datasets, @NonNull AutofillId autofillId, @NonNull AutoFillUI.AutoFillUiCallback client, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId) { if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called"); final Consumer<IntentSender> intentSenderConsumer = (intentSender) -> client.startIntentSender(intentSender, new Intent()); @@ -90,7 +92,8 @@ final class InlineSuggestionFactory { return createInlineSuggestionsInternal(/* isAugmented= */ false, request, datasets, autofillId, - onErrorCallback, onClickFactory, intentSenderConsumer, remoteRenderService); + onErrorCallback, onClickFactory, intentSenderConsumer, remoteRenderService, userId, + sessionId); } /** @@ -104,7 +107,8 @@ final class InlineSuggestionFactory { @NonNull AutofillId autofillId, @NonNull InlineFillUi.InlineSuggestionUiCallback inlineSuggestionUiCallback, @NonNull Runnable onErrorCallback, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId) { if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called"); return createInlineSuggestionsInternal(/* isAugmented= */ true, request, datasets, autofillId, onErrorCallback, @@ -112,7 +116,7 @@ final class InlineSuggestionFactory { inlineSuggestionUiCallback.autofill(dataset, datasetIndex), (intentSender) -> inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()), - remoteRenderService); + remoteRenderService, userId, sessionId); } @Nullable @@ -121,7 +125,8 @@ final class InlineSuggestionFactory { @NonNull List<Dataset> datasets, @NonNull AutofillId autofillId, @NonNull Runnable onErrorCallback, @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Consumer<IntentSender> intentSenderConsumer, - @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { + @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId) { SparseArray<Pair<Dataset, InlineSuggestion>> response = new SparseArray<>(datasets.size()); for (int datasetIndex = 0; datasetIndex < datasets.size(); datasetIndex++) { final Dataset dataset = datasets.get(datasetIndex); @@ -139,7 +144,8 @@ final class InlineSuggestionFactory { InlineSuggestion inlineSuggestion = createInlineSuggestion(isAugmented, dataset, datasetIndex, mergedInlinePresentation(request, datasetIndex, inlinePresentation), - onClickFactory, remoteRenderService, onErrorCallback, intentSenderConsumer, + onClickFactory, remoteRenderService, userId, sessionId, + onErrorCallback, intentSenderConsumer, request.getHostInputToken(), request.getHostDisplayId()); response.append(datasetIndex, Pair.create(dataset, inlineSuggestion)); } @@ -151,6 +157,7 @@ final class InlineSuggestionFactory { @NonNull InlinePresentation inlinePresentation, @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId, @NonNull Runnable onErrorCallback, @NonNull Consumer<IntentSender> intentSenderConsumer, @Nullable IBinder hostInputToken, int displayId) { @@ -167,7 +174,8 @@ final class InlineSuggestionFactory { final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo, createInlineContentProvider(inlinePresentation, () -> onClickFactory.accept(dataset, datasetIndex), onErrorCallback, - intentSenderConsumer, remoteRenderService, hostInputToken, displayId)); + intentSenderConsumer, remoteRenderService, userId, sessionId, + hostInputToken, displayId)); return inlineSuggestion; } @@ -175,6 +183,7 @@ final class InlineSuggestionFactory { private static InlineSuggestion createInlineAuthSuggestion( @NonNull InlinePresentation inlinePresentation, @NonNull RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId, @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Runnable onErrorCallback, @NonNull Consumer<IntentSender> intentSenderConsumer, @Nullable IBinder hostInputToken, int displayId) { @@ -187,8 +196,8 @@ final class InlineSuggestionFactory { createInlineContentProvider(inlinePresentation, () -> onClickFactory.accept(null, AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED), - onErrorCallback, intentSenderConsumer, remoteRenderService, hostInputToken, - displayId)); + onErrorCallback, intentSenderConsumer, remoteRenderService, userId, + sessionId, hostInputToken, displayId)); } /** @@ -216,12 +225,13 @@ final class InlineSuggestionFactory { @NonNull Runnable onErrorCallback, @NonNull Consumer<IntentSender> intentSenderConsumer, @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId, @Nullable IBinder hostInputToken, int displayId) { RemoteInlineSuggestionViewConnector remoteInlineSuggestionViewConnector = new RemoteInlineSuggestionViewConnector( - remoteRenderService, inlinePresentation, hostInputToken, displayId, onClickAction, - onErrorCallback, intentSenderConsumer); + remoteRenderService, userId, sessionId, inlinePresentation, hostInputToken, + displayId, onClickAction, onErrorCallback, intentSenderConsumer); InlineContentProviderImpl inlineContentProvider = new InlineContentProviderImpl( remoteInlineSuggestionViewConnector, null); return inlineContentProvider; diff --git a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java index 9d23c171800d..7257255d1ee4 100644 --- a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java +++ b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java @@ -46,6 +46,8 @@ final class RemoteInlineSuggestionViewConnector { @Nullable private final IBinder mHostInputToken; private final int mDisplayId; + private final int mUserId; + private final int mSessionId; @NonNull private final Runnable mOnAutofillCallback; @@ -56,6 +58,7 @@ final class RemoteInlineSuggestionViewConnector { RemoteInlineSuggestionViewConnector( @Nullable RemoteInlineSuggestionRenderService remoteRenderService, + int userId, int sessionId, @NonNull InlinePresentation inlinePresentation, @Nullable IBinder hostInputToken, int displayId, @@ -66,6 +69,8 @@ final class RemoteInlineSuggestionViewConnector { mInlinePresentation = inlinePresentation; mHostInputToken = hostInputToken; mDisplayId = displayId; + mUserId = userId; + mSessionId = sessionId; mOnAutofillCallback = onAutofillCallback; mOnErrorCallback = onErrorCallback; @@ -82,7 +87,7 @@ final class RemoteInlineSuggestionViewConnector { if (mRemoteRenderService != null) { if (sDebug) Slog.d(TAG, "Request to recreate the UI"); mRemoteRenderService.renderSuggestion(callback, mInlinePresentation, width, height, - mHostInputToken, mDisplayId); + mHostInputToken, mDisplayId, mUserId, mSessionId); return true; } return false; |