Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9730b7b authored by sandeepbandaru's avatar sandeepbandaru
Browse files

Handle onBindingDied in ODI services correctly

Note: this is a fix targeting only ODI related impls of
ServiceConnector. The actual fix for ServiceConnector as whole is to
made in I990f5139e40df2590b767c48bb4768ec777d49a5
which will be checked in as a long term solution under b/418214801

- As detailed in b/415190060#comment22, the binderDied() and
  onBindingDied() implementation was marking mService=null, leading to
  the underlying ServiceConnection not calling unbindService, this
  change fixes that behavior for onBindingDied case.
- To avoid race between binderThread and mHandlerThread serving
  ServiceConnection callbacks, we ensure all work in `binderDied()`
  callback is also scheduled on the mHandlerThread.
- Also, since whenever onBindingDied would be invoked, we
  would also have an associated binderDied death-receipt, we propagate
  ServiceLifecycleCallback#onBinderDied incase of binderDied() only.
  This avoids duplicate signals to clients.

Bug: 415190060
Test: tested behavior locally
Flag: EXEMPT bugfix
Change-Id: If1730d697d4b6ea96f1e45af03dbe22a95733b9a
parent 800b1192
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ public interface ServiceConnector<I extends IInterface> {
            implements ServiceConnector<I>, ServiceConnection, IBinder.DeathRecipient, Runnable {

        static final boolean DEBUG = false;
        static final String LOG_TAG = "ServiceConnector.Impl";
        final String LOG_TAG = this.getClass().getSimpleName();

        private static final long DEFAULT_DISCONNECT_TIMEOUT_MS = 15_000;
        private static final long DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
@@ -468,7 +468,7 @@ public interface ServiceConnector<I extends IInterface> {
            }
        }

        private void cancelTimeout() {
        protected void cancelTimeout() {
            if (DEBUG) {
                logTrace();
            }
@@ -662,7 +662,7 @@ public interface ServiceConnector<I extends IInterface> {
            dispatchOnBinderDied();
        }

        private void dispatchOnBinderDied() {
        protected void dispatchOnBinderDied() {
            ServiceLifecycleCallbacks<I> serviceLifecycleCallbacks = mServiceLifecycleCallbacks;
            if (serviceLifecycleCallbacks != null) {
                serviceLifecycleCallbacks.onBinderDied();
+18 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.ondeviceintelligence;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_INCLUDE_CAPABILITIES;

import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -63,4 +64,21 @@ public class RemoteOnDeviceIntelligenceService extends
                TimeUnit.SECONDS.toMillis(30),
                mContext.getUserId());
    }

    @Override
    public void onBindingDied(@NonNull ComponentName name) {
        // When the binding dies, unbind to allow the service to be re-bound.
        unbind();
    }

    @Override
    public void binderDied() {
        // When the binder dies, dispatch the event to the clients
        // and cancel pending jobs.
        getJobHandler().post(() -> {
            dispatchOnBinderDied();
            cancelTimeout();
            cancelPendingJobs(); // TODO:418214801 - Evaluate if this can be removed.
        });
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.ondeviceintelligence;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_INCLUDE_CAPABILITIES;

import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -73,4 +74,21 @@ public class RemoteOnDeviceSandboxedInferenceService extends
                TimeUnit.SECONDS.toMillis(30),
                mContext.getUserId());
    }

    @Override
    public void onBindingDied(@NonNull ComponentName name) {
        // When the binding dies, unbind to allow the service to be re-bound.
        unbind();
    }

    @Override
    public void binderDied() {
        // When the binder dies, dispatch the event to the clients
        // and cancel pending jobs.
        getJobHandler().post(() -> {
            dispatchOnBinderDied();
            cancelTimeout();
            cancelPendingJobs(); // TODO:418214801 - Evaluate if this can be removed.
        });
    }
}