diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 256ca500f5dec..457f410d31524 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -3267,6 +3267,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mDestroyed) { return null; } + unlinkClientVultureLocked(); mUi.destroyAll(mPendingSaveUi, this, true); mUi.clearCallback(this); diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java index 0b2e2bf9de1c8..1ab985bdc49ad 100644 --- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java @@ -74,6 +74,9 @@ public final class AutoFillUI { private final @NonNull OverlayControl mOverlayControl; private final @NonNull UiModeManagerInternal mUiModeMgr; + private @Nullable Runnable mCreateFillUiRunnable; + private @Nullable AutoFillUiCallback mSaveUiCallback; + public interface AutoFillUiCallback { void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent, @Nullable Bundle extras); @@ -98,9 +101,13 @@ public final class AutoFillUI { mHandler.post(() -> { if (mCallback != callback) { if (mCallback != null) { - hideAllUiThread(mCallback); + if (isSaveUiShowing()) { + // keeps showing the save UI + hideFillUiUiThread(callback, true); + } else { + hideAllUiThread(mCallback); + } } - mCallback = callback; } }); @@ -193,7 +200,7 @@ public final class AutoFillUI { .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, response.getDatasets() == null ? 0 : response.getDatasets().size()); - mHandler.post(() -> { + final Runnable createFillUiRunnable = () -> { if (callback != mCallback) { return; } @@ -266,7 +273,15 @@ public final class AutoFillUI { } } }); - }); + }; + + if (isSaveUiShowing()) { + // postpone creating the fill UI for showing the save UI + if (sDebug) Slog.d(TAG, "postpone fill UI request.."); + mCreateFillUiRunnable = createFillUiRunnable; + } else { + mHandler.post(createFillUiRunnable); + } } /** @@ -298,23 +313,22 @@ public final class AutoFillUI { return; } hideAllUiThread(callback); + mSaveUiCallback = callback; mSaveUi = new SaveUi(mContext, pendingSaveUi, serviceLabel, serviceIcon, servicePackageName, componentName, info, valueFinder, mOverlayControl, new SaveUi.OnSaveListener() { @Override public void onSave() { log.setType(MetricsEvent.TYPE_ACTION); - hideSaveUiUiThread(mCallback); - if (mCallback != null) { - mCallback.save(); - } + hideSaveUiUiThread(callback); + callback.save(); destroySaveUiUiThread(pendingSaveUi, true); } @Override public void onCancel(IntentSender listener) { log.setType(MetricsEvent.TYPE_DISMISS); - hideSaveUiUiThread(mCallback); + hideSaveUiUiThread(callback); if (listener != null) { try { listener.sendIntent(mContext, 0, null, null, null); @@ -323,9 +337,7 @@ public final class AutoFillUI { + listener, e); } } - if (mCallback != null) { - mCallback.cancelSave(); - } + callback.cancelSave(); destroySaveUiUiThread(pendingSaveUi, true); } @@ -334,18 +346,14 @@ public final class AutoFillUI { if (log.getType() == MetricsEvent.TYPE_UNKNOWN) { log.setType(MetricsEvent.TYPE_CLOSE); - if (mCallback != null) { - mCallback.cancelSave(); - } + callback.cancelSave(); } mMetricsLogger.write(log); } @Override public void startIntentSender(IntentSender intentSender, Intent intent) { - if (mCallback != null) { - mCallback.startIntentSender(intentSender, intent); - } + callback.startIntentSender(intentSender, intent); } }, mUiModeMgr.isNightMode(), isUpdate, compatMode); }); @@ -379,6 +387,10 @@ public final class AutoFillUI { mHandler.post(() -> destroyAllUiThread(pendingSaveUi, callback, notifyClient)); } + public boolean isSaveUiShowing() { + return mSaveUi == null ? false : mSaveUi.isShowing(); + } + public void dump(PrintWriter pw) { pw.println("Autofill UI"); final String prefix = " "; @@ -413,7 +425,8 @@ public final class AutoFillUI { Slog.v(TAG, "hideSaveUiUiThread(): mSaveUi=" + mSaveUi + ", callback=" + callback + ", mCallback=" + mCallback); } - if (mSaveUi != null && (callback == null || callback == mCallback)) { + + if (mSaveUi != null && mSaveUiCallback == callback) { return mSaveUi.hide(); } return null; @@ -432,6 +445,7 @@ public final class AutoFillUI { if (sDebug) Slog.d(TAG, "destroySaveUiUiThread(): " + pendingSaveUi); mSaveUi.destroy(); mSaveUi = null; + mSaveUiCallback = null; if (pendingSaveUi != null && notifyClient) { try { if (sDebug) Slog.d(TAG, "destroySaveUiUiThread(): notifying client"); @@ -440,6 +454,12 @@ public final class AutoFillUI { Slog.e(TAG, "Error notifying client to set save UI state to hidden: " + e); } } + + if (mCreateFillUiRunnable != null) { + if (sDebug) Slog.d(TAG, "start the pending fill UI request.."); + mCreateFillUiRunnable.run(); + mCreateFillUiRunnable = null; + } } @android.annotation.UiThread diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index 3cbfcf1183635..d7114a0b9a620 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -177,7 +177,7 @@ final class SaveUi { boolean nightMode, boolean isUpdate, boolean compatMode) { if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode); mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT; - mPendingUi= pendingUi; + mPendingUi = pendingUi; mListener = new OneActionThenDestroyListener(listener); mOverlayControl = overlayControl; mServicePackageName = servicePackageName; @@ -624,6 +624,10 @@ final class SaveUi { return mPendingUi; } + boolean isShowing() { + return mDialog.isShowing(); + } + void destroy() { try { if (sDebug) Slog.d(TAG, "destroy()");