summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Philip P. Moltmann <moltmann@google.com> 2019-01-07 14:34:47 -0800
committer Philip P. Moltmann <moltmann@google.com> 2019-01-12 19:13:28 +0000
commit883ff1a65daf54d925f21daabcf5a0830f650796 (patch)
treee02c6504a7e70e7dbe3ccab2128b0da7afc7d2c4
parentd01084ebe84074872243aabd5a3156c2afd2419e (diff)
Automatically unbind for AbstractRemoteService
No need for services to think about unbinding anymore. Now the AbstractRemoteService counts how many requests are not yet finished and once the number of unfinished requests drops to zero, schedules an unbind. Bug: 117779333 Test: - Started settings which makes many calls to PermissionControllerManager. Saw the automatic unbind to eventually happen. - atest CtsContentCaptureServiceTestCases (with content capture enabled and with content capture disabled) - atest CtsAutoFillServiceTestCases (4 tests out of WebViewActivityTest fail without and with this change) Change-Id: Ief2f3512df5a1c55694c0c6b449079a49089bcde
-rw-r--r--core/java/com/android/internal/infra/AbstractRemoteService.java38
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteFillService.java3
2 files changed, 34 insertions, 7 deletions
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index c94c64a879b3..e8ac2239c3fd 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -39,6 +39,7 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
/**
* Base class representing a remote service.
@@ -93,6 +94,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
// Used just for debugging purposes (on dump)
private long mNextUnbind;
+ /** Requests that have been scheduled, but that are not finished yet */
+ private final ArrayList<PendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>();
+
/**
* Callback called when the service dies.
*
@@ -229,6 +233,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
.append(mComponentName.flattenToString()).println();
pw.append(prefix).append(tab).append("destroyed=")
.append(String.valueOf(mDestroyed)).println();
+ pw.append(prefix).append(tab).append("numUnfinishedRequests=")
+ .append(String.valueOf(mUnfinishedRequests.size()));
final boolean bound = handleIsBound();
pw.append(prefix).append(tab).append("bound=")
.append(String.valueOf(bound));
@@ -257,23 +263,37 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
* <p>This request must be responded by the service somehow (typically using a callback),
* othewise it will trigger a {@link PendingRequest#onTimeout(AbstractRemoteService)} if the
* service doesn't respond.
- *
- * <p><b>NOTE: </b>this request is responsible for calling {@link #scheduleUnbind()}.
*/
protected void scheduleRequest(@NonNull PendingRequest<S, I> pendingRequest) {
- cancelScheduledUnbind();
mHandler.sendMessage(obtainMessage(
AbstractRemoteService::handlePendingRequest, this, pendingRequest));
}
/**
+ * Marks a pendingRequest as finished.
+ *
+ * @param finshedRequest The request that is finished
+ */
+ void finishRequest(@NonNull PendingRequest<S, I> finshedRequest) {
+ mHandler.sendMessage(
+ obtainMessage(AbstractRemoteService::handleFinishRequest, this, finshedRequest));
+ }
+
+ private void handleFinishRequest(@NonNull PendingRequest<S, I> finshedRequest) {
+ mUnfinishedRequests.remove(finshedRequest);
+
+ if (mUnfinishedRequests.isEmpty()) {
+ scheduleUnbind();
+ }
+ }
+
+ /**
* Schedules an async request.
*
* <p>This request is not expecting a callback from the service, hence it's represented by
* a simple {@link Runnable}.
*/
protected void scheduleAsyncRequest(@NonNull AsyncRequest<I> request) {
- scheduleUnbind();
// TODO(b/117779333): fix generics below
@SuppressWarnings({"unchecked", "rawtypes"})
final MyAsyncPendingRequest<S, I> asyncRequest = new MyAsyncPendingRequest(this, request);
@@ -341,6 +361,10 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
handleEnsureBound();
} else {
if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
+
+ mUnfinishedRequests.add(pendingRequest);
+ cancelScheduledUnbind();
+
pendingRequest.run();
if (pendingRequest.isFinal()) {
mCompleted = true;
@@ -504,6 +528,12 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
}
mCompleted = true;
}
+
+ S service = mWeakService.get();
+ if (service != null) {
+ service.finishRequest(this);
+ }
+
mServiceHandler.removeCallbacks(mTimeoutTrigger);
return true;
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 34fe5d916356..e8a52b4a12a9 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -139,9 +139,6 @@ final class RemoteFillService
if (mPendingRequest == pendingRequest) {
mPendingRequest = null;
}
- if (mPendingRequest == null) {
- scheduleUnbind();
- }
return true;
}