Merge "Destroy fill UI when app dies." into pi-dev
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index bcfe1b6..5eee9ed 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.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.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 @@
@GuardedBy("mLock")
private IAutoFillManagerClient mClient;
+ @GuardedBy("mLock")
+ private DeathRecipient mClientVulture;
+
private final RemoteFillService mRemoteFillService;
@GuardedBy("mLock")
@@ -509,7 +512,7 @@
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 @@
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 @@
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 e28a204..21a39e4 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 @@
* Hides the fill UI.
*/
public void hideFillUi(@NonNull AutoFillUiCallback callback) {
- mHandler.post(() -> hideFillUiUiThread(callback));
+ mHandler.post(() -> hideFillUiUiThread(callback, true));
}
/**
@@ -189,7 +189,7 @@
@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 @@
@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 @@
@Override
public void onCanceled() {
log.setType(MetricsEvent.TYPE_DISMISS);
- hideFillUiUiThread(callback);
+ hideFillUiUiThread(callback, true);
}
@Override
@@ -367,9 +367,9 @@
}
@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 @@
@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 a32078c..ef4656b 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 @@
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 @@
* Hides the window.
*/
void hide() {
+ hide(true);
+ }
+
+ void hide(boolean destroyCallbackOnError) {
try {
if (mShowing) {
mWm.removeView(mContentView);
@@ -654,7 +663,9 @@
// 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();
}