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

Commit c11cf3cf authored by Bryce Lee's avatar Bryce Lee
Browse files

Fix DreamOverlayService memory leaks.

This changelist addresses a various points where references retain the
DreamOverlayService and/or its child members after the service is
destroyed.

Fixes: 5897130
Test: atest TouchMonitorTest#testDestroy_cleansUpHandler
Test: atest DreamOverlayContainerViewControllerTest#destroy_cleansUpState
Test: atest DreamOverlayServiceTest#testResetCurrentOverlayWhenConnectedToNewDream
Flag: EXEMPT bugfix
Change-Id: I5e9ea0e27f7219d9252b1480bbbc880851d2a496
parent e27a8ea8
Loading
Loading
Loading
Loading
+34 −11
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManager;

import java.lang.ref.WeakReference;
import java.util.concurrent.Executor;
import java.util.function.Consumer;


/**
@@ -52,43 +54,51 @@ public abstract class DreamOverlayService extends Service {
    // An {@link IDreamOverlayClient} implementation that identifies itself when forwarding
    // requests to the {@link DreamOverlayService}
    private static class OverlayClient extends IDreamOverlayClient.Stub {
        private final DreamOverlayService mService;
        private final WeakReference<DreamOverlayService> mService;
        private boolean mShowComplications;
        private ComponentName mDreamComponent;
        IDreamOverlayCallback mDreamOverlayCallback;

        OverlayClient(DreamOverlayService service) {
        OverlayClient(WeakReference<DreamOverlayService> service) {
            mService = service;
        }

        private void applyToDream(Consumer<DreamOverlayService> consumer) {
            final DreamOverlayService service = mService.get();

            if (service != null) {
                consumer.accept(service);
            }
        }

        @Override
        public void startDream(WindowManager.LayoutParams params, IDreamOverlayCallback callback,
                String dreamComponent, boolean shouldShowComplications) throws RemoteException {
            mDreamComponent = ComponentName.unflattenFromString(dreamComponent);
            mShowComplications = shouldShowComplications;
            mDreamOverlayCallback = callback;
            mService.startDream(this, params);
            applyToDream(dreamOverlayService -> dreamOverlayService.startDream(this, params));
        }

        @Override
        public void wakeUp() {
            mService.wakeUp(this);
            applyToDream(dreamOverlayService -> dreamOverlayService.wakeUp(this));
        }

        @Override
        public void endDream() {
            mService.endDream(this);
            applyToDream(dreamOverlayService -> dreamOverlayService.endDream(this));
        }

        @Override
        public void comeToFront() {
            mService.comeToFront(this);
            applyToDream(dreamOverlayService -> dreamOverlayService.comeToFront(this));
        }

        @Override
        public void onWakeRequested() {
            if (Flags.dreamWakeRedirect()) {
                mService.onWakeRequested();
                applyToDream(DreamOverlayService::onWakeRequested);
            }
        }

@@ -161,17 +171,24 @@ public abstract class DreamOverlayService extends Service {
        });
    }

    private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
    private static class DreamOverlay extends IDreamOverlay.Stub {
        private final WeakReference<DreamOverlayService> mService;

        DreamOverlay(DreamOverlayService service) {
            mService = new WeakReference<>(service);
        }

        @Override
        public void getClient(IDreamOverlayClientCallback callback) {
            try {
                callback.onDreamOverlayClient(
                        new OverlayClient(DreamOverlayService.this));
                callback.onDreamOverlayClient(new OverlayClient(mService));
            } catch (RemoteException e) {
                Log.e(TAG, "could not send client to callback", e);
            }
        }
    };
    }

    private final IDreamOverlay mDreamOverlay = new DreamOverlay(this);

    public DreamOverlayService() {
    }
@@ -195,6 +212,12 @@ public abstract class DreamOverlayService extends Service {
        }
    }

    @Override
    public void onDestroy() {
        mCurrentClient = null;
        super.onDestroy();
    }

    @Nullable
    @Override
    public final IBinder onBind(@NonNull Intent intent) {
+10 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -324,4 +325,13 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
        // enabled.
        mController.onViewAttached();
    }

    @Test
    public void destroy_cleansUpState() {
        mController.destroy();
        verify(mStateController).removeCallback(any());
        verify(mAmbientStatusBarViewController).destroy();
        verify(mComplicationHostViewController).destroy();
        verify(mLowLightTransitionCoordinator).setLowLightEnterListener(ArgumentMatchers.isNull());
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -596,6 +596,9 @@ class DreamOverlayServiceTest : SysuiTestCase() {
        // are created.
        verify(mDreamOverlayComponent).getDreamOverlayContainerViewController()
        verify(mAmbientTouchComponent).getTouchMonitor()

        // Verify DreamOverlayContainerViewController is destroyed.
        verify(mDreamOverlayContainerViewController).destroy()
    }

    @Test
+5 −0
Original line number Diff line number Diff line
@@ -122,4 +122,9 @@ public interface TouchHandler {
     * @param session
     */
    void onSessionStart(TouchSession session);

    /**
     * Called when the handler is being torn down.
     */
    default void onDestroy() {}
}
+4 −0
Original line number Diff line number Diff line
@@ -581,6 +581,10 @@ public class TouchMonitor {
            mBoundsFlow.cancel(new CancellationException());
        }

        for (TouchHandler handler : mHandlers) {
            handler.onDestroy();
        }

        mInitialized = false;
    }

Loading