diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 6eb71f747be6f..c43beea98c7e2 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -52,6 +52,7 @@ import android.view.contentcapture.ViewNode.ViewStructureImpl; import com.android.internal.os.IResultReceiver; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -146,7 +147,44 @@ public final class MainContentCaptureSession extends ContentCaptureSession { * Binder object used to update the session state. */ @NonNull - private final IResultReceiver.Stub mSessionStateReceiver; + private final SessionStateReceiver mSessionStateReceiver; + + private static class SessionStateReceiver extends IResultReceiver.Stub { + private final WeakReference mMainSession; + + SessionStateReceiver(MainContentCaptureSession session) { + mMainSession = new WeakReference<>(session); + } + + @Override + public void send(int resultCode, Bundle resultData) { + final MainContentCaptureSession mainSession = mMainSession.get(); + if (mainSession == null) { + Log.w(TAG, "received result after mina session released"); + return; + } + final IBinder binder; + if (resultData != null) { + // Change in content capture enabled. + final boolean hasEnabled = resultData.getBoolean(EXTRA_ENABLED_STATE); + if (hasEnabled) { + final boolean disabled = (resultCode == RESULT_CODE_FALSE); + mainSession.mDisabled.set(disabled); + return; + } + binder = resultData.getBinder(EXTRA_BINDER); + if (binder == null) { + Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result"); + mainSession.mHandler.post(() -> mainSession.resetSession( + STATE_DISABLED | STATE_INTERNAL_ERROR)); + return; + } + } else { + binder = null; + } + mainSession.mHandler.post(() -> mainSession.onSessionStarted(resultCode, binder)); + } + } protected MainContentCaptureSession(@NonNull Context context, @NonNull ContentCaptureManager manager, @NonNull Handler handler, @@ -159,32 +197,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { final int logHistorySize = mManager.mOptions.logHistorySize; mFlushHistory = logHistorySize > 0 ? new LocalLog(logHistorySize) : null; - mSessionStateReceiver = new IResultReceiver.Stub() { - @Override - public void send(int resultCode, Bundle resultData) { - final IBinder binder; - if (resultData != null) { - // Change in content capture enabled. - final boolean hasEnabled = resultData.getBoolean(EXTRA_ENABLED_STATE); - if (hasEnabled) { - final boolean disabled = (resultCode == RESULT_CODE_FALSE); - mDisabled.set(disabled); - return; - } - binder = resultData.getBinder(EXTRA_BINDER); - if (binder == null) { - Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result"); - mHandler.post(() -> resetSession( - STATE_DISABLED | STATE_INTERNAL_ERROR)); - return; - } - } else { - binder = null; - } - mHandler.post(() -> onSessionStarted(resultCode, binder)); - } - }; - + mSessionStateReceiver = new SessionStateReceiver(this); } @Override @@ -543,6 +556,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { Log.e(TAG, "Error destroying system-service session " + mId + " for " + getDebugState() + ": " + e); } + + if (mDirectServiceInterface != null) { + mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0); + } + mDirectServiceInterface = null; } // TODO(b/122454205): once we support multiple sessions, we might need to move some of these