summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/com/android/internal/infra/AbstractRemoteService.java44
1 files changed, 38 insertions, 6 deletions
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 33918400d571..9471e69d21bd 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -33,6 +33,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
+import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -64,6 +65,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
I extends IInterface> implements DeathRecipient {
private static final int MSG_UNBIND = 1;
+ protected static final long PERMANENT_BOUND_TIMEOUT_MS = 0;
+
protected static final int LAST_PRIVATE_MSG = MSG_UNBIND;
// TODO(b/117779333): convert all booleans into an integer / flags
@@ -86,6 +89,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
private boolean mServiceDied;
private boolean mCompleted;
+ // Used just for debugging purposes (on dump)
+ private long mNextUnbind;
+
/**
* Callback called when the service dies.
*
@@ -156,7 +162,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
protected abstract I getServiceInterface(@NonNull IBinder service);
/**
- * Defines How long after the last interaction with the service we would unbind.
+ * Defines how long after the last interaction with the service we would unbind.
+ *
+ * @return time to unbind (in millis), or {@link #PERMANENT_BOUND_TIMEOUT_MS} to not unbind.
*/
protected abstract long getTimeoutIdleBindMillis();
@@ -220,11 +228,23 @@ 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();
+ final boolean bound = handleIsBound();
pw.append(prefix).append(tab).append("bound=")
- .append(String.valueOf(handleIsBound())).println();
+ .append(String.valueOf(bound));
+ final long idleTimeout = getTimeoutIdleBindMillis();
+ if (bound) {
+ if (idleTimeout > 0) {
+ pw.append(" (unbind in : ");
+ TimeUtils.formatDuration(mNextUnbind - SystemClock.elapsedRealtime(), pw);
+ pw.append(")");
+ } else {
+ pw.append(" (permanently bound)");
+ }
+ }
+ pw.println();
pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
pw.append(prefix).append("idleTimeout=")
- .append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println();
+ .append(Long.toString(idleTimeout / 1000)).append("s").println();
pw.append(prefix).append("requestTimeout=")
.append(Long.toString(getRemoteRequestMillis() / 1000)).append("s").println();
pw.println();
@@ -236,6 +256,8 @@ 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();
@@ -250,7 +272,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
* a simple {@link Runnable}.
*/
protected void scheduleAsyncRequest(@NonNull AsyncRequest<I> request) {
- cancelScheduledUnbind();
+ scheduleUnbind();
// TODO(b/117779333): fix generics below
@SuppressWarnings({"unchecked", "rawtypes"})
final MyAsyncPendingRequest<S, I> asyncRequest = new MyAsyncPendingRequest(this, request);
@@ -263,12 +285,21 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
}
protected void scheduleUnbind() {
+ final long unbindDelay = getTimeoutIdleBindMillis();
+
+ if (unbindDelay <= 0) {
+ if (mVerbose) Slog.v(mTag, "not scheduling unbind when value is " + unbindDelay);
+ return;
+ }
+
cancelScheduledUnbind();
- // TODO(b/111276913): implement "permanent binding"
// TODO(b/117779333): make sure it's unbound if the service settings changing (right now
// it's not)
+
+ mNextUnbind = SystemClock.elapsedRealtime() + unbindDelay;
+ if (mVerbose) Slog.v(mTag, "unbinding in " + unbindDelay + "ms: " + mNextUnbind);
mHandler.sendMessageDelayed(obtainMessage(AbstractRemoteService::handleUnbind, this)
- .setWhat(MSG_UNBIND), getTimeoutIdleBindMillis());
+ .setWhat(MSG_UNBIND), unbindDelay);
}
private void handleUnbind() {
@@ -342,6 +373,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
mService = null;
}
}
+ mNextUnbind = 0;
mContext.unbindService(mServiceConnection);
}