diff options
3 files changed, 60 insertions, 14 deletions
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index bcfe1b6eb1f3..5eee9ed6c9b2 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -52,6 +52,7 @@ import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.IBinder.DeathRecipient; import android.os.Parcelable; import android.os.RemoteCallback; import android.os.RemoteException; @@ -87,7 +88,6 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.os.HandlerCaller; import com.android.internal.util.ArrayUtils; import com.android.server.autofill.ui.AutoFillUI; import com.android.server.autofill.ui.PendingUi; @@ -158,6 +158,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private IAutoFillManagerClient mClient; + @GuardedBy("mLock") + private DeathRecipient mClientVulture; + private final RemoteFillService mRemoteFillService; @GuardedBy("mLock") @@ -509,7 +512,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mWtfHistory = wtfHistory; mComponentName = componentName; mCompatMode = compatMode; - mClient = IAutoFillManagerClient.Stub.asInterface(client); + setClientLocked(client); mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED) .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); @@ -539,13 +542,44 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } mActivityToken = newActivity; - mClient = IAutoFillManagerClient.Stub.asInterface(newClient); + setClientLocked(newClient); // The tracked id are not persisted in the client, hence update them updateTrackedIdsLocked(); } } + @GuardedBy("mLock") + private void setClientLocked(@NonNull IBinder client) { + unlinkClientVultureLocked(); + mClient = IAutoFillManagerClient.Stub.asInterface(client); + mClientVulture = () -> { + Slog.d(TAG, "handling death of " + mActivityToken + " when saving=" + mIsSaving); + synchronized (mLock) { + if (mIsSaving) { + mUi.hideFillUi(this); + } else { + mUi.destroyAll(mPendingSaveUi, this, false); + } + } + }; + try { + mClient.asBinder().linkToDeath(mClientVulture, 0); + } catch (RemoteException e) { + Slog.w(TAG, "could not set binder death listener on autofill client: " + e); + } + } + + @GuardedBy("mLock") + private void unlinkClientVultureLocked() { + if (mClient != null && mClientVulture != null) { + final boolean unlinked = mClient.asBinder().unlinkToDeath(mClientVulture, 0); + if (!unlinked) { + Slog.w(TAG, "unlinking vulture from death failed for " + mActivityToken); + } + } + } + // FillServiceCallbacks @Override public void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, @@ -2443,6 +2477,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mDestroyed) { return null; } + unlinkClientVultureLocked(); mUi.destroyAll(mPendingSaveUi, this, true); mUi.clearCallback(this); mDestroyed = true; 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 e28a204df787..21a39e483986 100644 --- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java @@ -136,7 +136,7 @@ public final class AutoFillUI { * Hides the fill UI. */ public void hideFillUi(@NonNull AutoFillUiCallback callback) { - mHandler.post(() -> hideFillUiUiThread(callback)); + mHandler.post(() -> hideFillUiUiThread(callback, true)); } /** @@ -189,7 +189,7 @@ public final class AutoFillUI { @Override public void onResponsePicked(FillResponse response) { log.setType(MetricsEvent.TYPE_DETAIL); - hideFillUiUiThread(callback); + hideFillUiUiThread(callback, true); if (mCallback != null) { mCallback.authenticate(response.getRequestId(), AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED, @@ -200,7 +200,7 @@ public final class AutoFillUI { @Override public void onDatasetPicked(Dataset dataset) { log.setType(MetricsEvent.TYPE_ACTION); - hideFillUiUiThread(callback); + hideFillUiUiThread(callback, true); if (mCallback != null) { final int datasetIndex = response.getDatasets().indexOf(dataset); mCallback.fill(response.getRequestId(), datasetIndex, dataset); @@ -210,7 +210,7 @@ public final class AutoFillUI { @Override public void onCanceled() { log.setType(MetricsEvent.TYPE_DISMISS); - hideFillUiUiThread(callback); + hideFillUiUiThread(callback, true); } @Override @@ -367,9 +367,9 @@ public final class AutoFillUI { } @android.annotation.UiThread - private void hideFillUiUiThread(@Nullable AutoFillUiCallback callback) { + private void hideFillUiUiThread(@Nullable AutoFillUiCallback callback, boolean notifyClient) { if (mFillUi != null && (callback == null || callback == mCallback)) { - mFillUi.destroy(); + mFillUi.destroy(notifyClient); mFillUi = null; } } @@ -413,13 +413,13 @@ public final class AutoFillUI { @android.annotation.UiThread private void destroyAllUiThread(@Nullable PendingUi pendingSaveUi, @Nullable AutoFillUiCallback callback, boolean notifyClient) { - hideFillUiUiThread(callback); + hideFillUiUiThread(callback, notifyClient); destroySaveUiUiThread(pendingSaveUi, notifyClient); } @android.annotation.UiThread private void hideAllUiThread(@Nullable AutoFillUiCallback callback) { - hideFillUiUiThread(callback); + hideFillUiUiThread(callback, true); final PendingUi pendingSaveUi = hideSaveUiUiThread(callback); if (pendingSaveUi != null && pendingSaveUi.getState() == PendingUi.STATE_FINISHED) { if (sDebug) { diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index a32078cc8e9f..ef4656bd06bb 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -415,10 +415,15 @@ final class FillUi { applyNewFilterText(); } - public void destroy() { + public void destroy(boolean notifyClient) { throwIfDestroyed(); + if (mWindow != null) { + mWindow.hide(false); + } mCallback.onDestroy(); - mCallback.requestHideFillUi(); + if (notifyClient) { + mCallback.requestHideFillUi(); + } mDestroyed = true; } @@ -644,6 +649,10 @@ final class FillUi { * Hides the window. */ void hide() { + hide(true); + } + + void hide(boolean destroyCallbackOnError) { try { if (mShowing) { mWm.removeView(mContentView); @@ -654,7 +663,9 @@ final class FillUi { // happen - since show() and hide() are always called in the UIThread - but if it // does, it should not crash the system. Slog.e(TAG, "Exception hiding window ", e); - mCallback.onDestroy(); + if (destroyCallbackOnError) { + mCallback.onDestroy(); + } } finally { mOverlayControl.showOverlays(); } |