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

Commit 705b6af1 authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

Fix disconnection bug in ServiceWatcher

Context.unbind() does not result in any callback to
onServiceDisconnected(), even though that might be expected. Do the
callback ourselves if necessary to ensure that clients always see
disconnections.

Bug: 151182828
Test: manual
Change-Id: I4969d4f548a6ff7256a4833d61cdd1263ca1dfde
parent 4256be1c
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ public class ServiceWatcher implements ServiceConnection {
        @Nullable public final ComponentName component;
        @UserIdInt public final int userId;

        private ServiceInfo(ResolveInfo resolveInfo, int currentUserId) {
        ServiceInfo(ResolveInfo resolveInfo, int currentUserId) {
            Preconditions.checkArgument(resolveInfo.serviceInfo.getComponentName() != null);

            Bundle metadata = resolveInfo.serviceInfo.metaData;
@@ -316,6 +316,7 @@ public class ServiceWatcher implements ServiceConnection {
            }

            mContext.unbindService(this);
            onServiceDisconnected(mServiceInfo.component);
            mServiceInfo = ServiceInfo.NONE;
        }

@@ -339,15 +340,13 @@ public class ServiceWatcher implements ServiceConnection {
    @Override
    public final void onServiceConnected(ComponentName component, IBinder binder) {
        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
        Preconditions.checkState(mBinder == null);

        if (D) {
            Log.i(TAG, getLogPrefix() + " connected to " + component.toShortString());
        }

        mBinder = binder;

        // we always run the on bind callback even if we know that the binder is dead already so
        // that there are always balance pairs of bind/unbind callbacks
        if (mOnBind != null) {
            try {
                mOnBind.run(binder);
@@ -357,19 +356,16 @@ public class ServiceWatcher implements ServiceConnection {
                Log.e(TAG, getLogPrefix() + " exception running on " + mServiceInfo, e);
            }
        }

        try {
            // setting the binder to null lets us skip queued transactions
            binder.linkToDeath(() -> mBinder = null, 0);
        } catch (RemoteException e) {
            mBinder = null;
        }
    }

    @Override
    public final void onServiceDisconnected(ComponentName component) {
        Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());

        if (mBinder == null) {
            return;
        }

        if (D) {
            Log.i(TAG, getLogPrefix() + " disconnected from " + component.toShortString());
        }
@@ -391,18 +387,18 @@ public class ServiceWatcher implements ServiceConnection {
        onBestServiceChanged(true);
    }

    private void onUserSwitched(@UserIdInt int userId) {
    void onUserSwitched(@UserIdInt int userId) {
        mCurrentUserId = userId;
        onBestServiceChanged(false);
    }

    private void onUserUnlocked(@UserIdInt int userId) {
    void onUserUnlocked(@UserIdInt int userId) {
        if (userId == mCurrentUserId) {
            onBestServiceChanged(false);
        }
    }

    private void onPackageChanged(String packageName) {
    void onPackageChanged(String packageName) {
        // force a rebind if the changed package was the currently connected package
        String currentPackageName =
                mServiceInfo.component != null ? mServiceInfo.component.getPackageName() : null;