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

Commit 95a0a7ff authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Add guards around unbind

Also, make sure that mIsBound is in the correct state and clean up after
death.

Test: atest TileServiceTest for the leaks
Test: atest TileLifecycleManagerTest
Fixes: 183807631
Change-Id: I8fa2b746d9ba273bcbef088e4ca4ba50a317128a
parent 1d2cbb6f
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import androidx.annotation.VisibleForTesting;

import com.android.systemui.broadcast.BroadcastDispatcher;

import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -204,9 +205,14 @@ public class TileLifecycleManager extends BroadcastReceiver implements
            if (DEBUG) Log.d(TAG, "Unbinding service " + mIntent + " " + mUser);
            // Give it another chance next time it needs to be bound, out of kindness.
            mBindTryCount = 0;
            mWrapper = null;
            freeWrapper();
            if (mIsBound) {
                try {
                    mContext.unbindService(this);
                } catch (Exception e) {
                    Log.e(TAG, "Failed to unbind service "
                            + mIntent.getComponent().flattenToShortString(), e);
                }
                mIsBound = false;
            }
        }
@@ -290,7 +296,9 @@ public class TileLifecycleManager extends BroadcastReceiver implements

    private void handleDeath() {
        if (mWrapper == null) return;
        mWrapper = null;
        freeWrapper();
        // Clearly not bound anymore
        mIsBound = false;
        if (!mBound) return;
        if (DEBUG) Log.d(TAG, "handleDeath");
        if (checkComponentState()) {
@@ -472,6 +480,18 @@ public class TileLifecycleManager extends BroadcastReceiver implements
        return mToken;
    }

    private void freeWrapper() {
        if (mWrapper != null) {
            try {
                mWrapper.asBinder().unlinkToDeath(this, 0);
            } catch (NoSuchElementException e) {
                Log.w(TAG, "Trying to unlink not linked recipient for component"
                        + mIntent.getComponent().flattenToShortString());
            }
            mWrapper = null;
        }
    }

    public interface TileChangeListener {
        void onTileChanged(ComponentName tile);
    }
+1 −1
Original line number Diff line number Diff line
@@ -77,10 +77,10 @@ public class TileLifecycleManagerTest extends SysuiTestCase {

        // Stub.asInterface will just return itself.
        when(mMockTileService.queryLocalInterface(anyString())).thenReturn(mMockTileService);
        when(mMockTileService.asBinder()).thenReturn(mMockTileService);

        mContext.addMockService(mTileServiceComponentName, mMockTileService);


        mTileServiceIntent = new Intent().setComponent(mTileServiceComponentName);
        mUser = new UserHandle(UserHandle.myUserId());
        mThread = new HandlerThread("TestThread");