Merge "Fixed and improved (for reuse) PendingRequest lifecycle." into oc-dev
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 35f4fae..9aebf6d 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -404,10 +404,86 @@
}
private static abstract class PendingRequest implements Runnable {
- void cancel() {
+ protected final Object mLock = new Object();
+ private final WeakReference<RemoteFillService> mWeakService;
+ private final Runnable mTimeoutTrigger;
+ private final Handler mServiceHandler;
+
+ @GuardedBy("mLock")
+ private boolean mCancelled;
+
+ @GuardedBy("mLock")
+ private boolean mCompleted;
+
+ PendingRequest(RemoteFillService service) {
+ mWeakService = new WeakReference<>(service);
+ mServiceHandler = service.mHandler.getHandler();
+ mTimeoutTrigger = () -> {
+ synchronized (mLock) {
+ if (mCancelled) {
+ return;
+ }
+ mCompleted = true;
+ }
+
+ final RemoteFillService remoteService = mWeakService.get();
+ if (remoteService != null) {
+ fail(remoteService);
+ }
+ };
+ mServiceHandler.postAtTime(mTimeoutTrigger,
+ SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
}
+ protected RemoteFillService getService() {
+ return mWeakService.get();
+ }
+
+ /**
+ * Sub-classes must call this method when the remote service finishes, i.e., when it
+ * called {@code onFill...} or {@code onSave...}.
+ *
+ * @return {@code false} in the service is already finished, {@code true} otherwise.
+ */
+ protected final boolean finish() {
+ synchronized (mLock) {
+ if (mCompleted || mCancelled) {
+ return false;
+ }
+ mCompleted = true;
+ }
+ mServiceHandler.removeCallbacks(mTimeoutTrigger);
+ return true;
+ }
+
+ protected boolean isCancelledLocked() {
+ return mCancelled;
+ }
+
+ /**
+ * Cancels the service.
+ *
+ * @return {@code false} if service is already canceled, {@code true} otherwise.
+ */
+ boolean cancel() {
+ synchronized (mLock) {
+ if (mCancelled || mCompleted) {
+ return false;
+ }
+ mCancelled = true;
+ }
+
+ mServiceHandler.removeCallbacks(mTimeoutTrigger);
+ return true;
+ }
+
+ /**
+ * Called by the self-destructure timeout when the AutofilllService didn't reply to the
+ * request on time.
+ */
+ abstract void fail(RemoteFillService remoteService);
+
/**
* @return whether this request leads to a final state where no
* other requests can be made.
@@ -418,22 +494,14 @@
}
private static final class PendingFillRequest extends PendingRequest {
- private final Object mLock = new Object();
-
- private final WeakReference<RemoteFillService> mWeakService;
private final FillRequest mRequest;
private final IFillCallback mCallback;
private ICancellationSignal mCancellation;
- @GuardedBy("mLock")
- private boolean mCancelled;
-
- @GuardedBy("mLock")
- private boolean mCompleted;
-
public PendingFillRequest(FillRequest request, RemoteFillService service) {
+ super(service);
mRequest = request;
- mWeakService = new WeakReference<>(service);
+
mCallback = new IFillCallback.Stub() {
@Override
public void onCancellable(ICancellationSignal cancellation) {
@@ -441,7 +509,7 @@
final boolean cancelled;
synchronized (mLock) {
mCancellation = cancellation;
- cancelled = mCancelled;
+ cancelled = isCancelledLocked();
}
if (cancelled) {
try {
@@ -455,15 +523,10 @@
@Override
public void onSuccess(FillResponse response) {
- synchronized (mLock) {
- if (mCompleted) {
- return;
- }
- mCompleted = true;
- }
- RemoteFillService remoteService = mWeakService.get();
+ if (!finish()) return;
+
+ final RemoteFillService remoteService = getService();
if (remoteService != null) {
- service.mHandler.getHandler().removeCallbacks(PendingFillRequest.this);
remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this,
getCallingUid(), request.getFlags(), response);
}
@@ -471,132 +534,100 @@
@Override
public void onFailure(CharSequence message) {
- synchronized (mLock) {
- if (mCompleted) {
- return;
- }
- mCompleted = true;
- }
- RemoteFillService remoteService = mWeakService.get();
+ if (!finish()) return;
+
+ final RemoteFillService remoteService = getService();
if (remoteService != null) {
- service.mHandler.getHandler().removeCallbacks(PendingFillRequest.this);
remoteService.dispatchOnFillRequestFailure(
PendingFillRequest.this, message);
}
}
};
- service.mHandler.getHandler().postAtTime(() -> {
- cancel();
- try {
- mCallback.onFailure(null);
- } catch (RemoteException e) {
- /* ignore */
- }
- }, PendingFillRequest.this,
- SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
+ }
+
+ @Override
+ void fail(RemoteFillService remoteService) {
+ remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
}
@Override
public void run() {
- RemoteFillService remoteService = mWeakService.get();
+ final RemoteFillService remoteService = getService();
if (remoteService != null) {
try {
remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
} catch (RemoteException e) {
Slog.e(LOG_TAG, "Error calling on fill request", e);
- cancel();
+
+ remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
}
}
}
@Override
- public void cancel() {
- final ICancellationSignal cancellation;
- synchronized (mLock) {
- if (mCancelled) {
- return;
+ public boolean cancel() {
+ if (!super.cancel()) return false;
+
+ final ICancellationSignal cancellation = mCancellation;
+ if (cancellation != null) {
+ try {
+ cancellation.cancel();
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Error cancelling a fill request", e);
}
- mCancelled = true;
- cancellation = mCancellation;
}
- if (cancellation == null) {
- return;
- }
- try {
- cancellation.cancel();
- } catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error cancelling a fill request", e);
- }
+ return true;
}
}
private static final class PendingSaveRequest extends PendingRequest {
- private final Object mLock = new Object();
-
- private final WeakReference<RemoteFillService> mWeakService;
private final SaveRequest mRequest;
private final ISaveCallback mCallback;
- @GuardedBy("mLock")
- private boolean mCompleted;
-
public PendingSaveRequest(@NonNull SaveRequest request,
@NonNull RemoteFillService service) {
+ super(service);
mRequest = request;
- mWeakService = new WeakReference<>(service);
+
mCallback = new ISaveCallback.Stub() {
@Override
public void onSuccess() {
- synchronized (mLock) {
- if (mCompleted) {
- return;
- }
- mCompleted = true;
- }
- cancel();
- RemoteFillService service = mWeakService.get();
- if (service != null) {
- service.mHandler.getHandler().removeCallbacks(PendingSaveRequest.this);
- service.dispatchOnSaveRequestSuccess(
- PendingSaveRequest.this);
+ if (!finish()) return;
+
+ final RemoteFillService remoteService = getService();
+ if (remoteService != null) {
+ remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this);
}
}
@Override
public void onFailure(CharSequence message) {
- synchronized (mLock) {
- if (mCompleted) {
- return;
- }
- mCompleted = true;
- }
- RemoteFillService service = mWeakService.get();
- if (service != null) {
- service.mHandler.getHandler().removeCallbacks(PendingSaveRequest.this);
- service.dispatchOnSaveRequestFailure(
- PendingSaveRequest.this, message);
+ if (!finish()) return;
+
+ final RemoteFillService remoteService = getService();
+ if (remoteService != null) {
+ remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this,
+ message);
}
}
};
- service.mHandler.getHandler().postAtTime(() -> {
- cancel();
- try {
- mCallback.onFailure(null);
- } catch (RemoteException e) {
- /* ignore */
- }
- }, PendingSaveRequest.this,
- SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
+ }
+
+ @Override
+ void fail(RemoteFillService remoteService) {
+ remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this, null);
}
@Override
public void run() {
- final RemoteFillService service = mWeakService.get();
- if (service != null) {
+ final RemoteFillService remoteService = getService();
+ if (remoteService != null) {
try {
- service.mAutoFillService.onSaveRequest(mRequest, mCallback);
+ remoteService.mAutoFillService.onSaveRequest(mRequest, mCallback);
} catch (RemoteException e) {
Slog.e(LOG_TAG, "Error calling on save request", e);
+
+ remoteService.dispatchOnFillRequestFailure(PendingSaveRequest.this, null);
}
}
}