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

Commit 43b73180 authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas
Browse files

Fix launcher activity leaking when desktop windowing enabled

When desktop windowing is enabled we initiate the
`SplitFromDesktopController` within the `SplitSelectStateController`
which registers a `SplitSelectListener` on the launcher instance.
However when we destroy the `SplitSelectStateController` the
`SplitFromDesktopController` is not destroyed an thus any listeners are
not unregisterd. Instead we should explicitly destroy the
`SplitFromDesktopController` by unregistering listener.

Flag: NONE
Fixes: 332667403
Bug: 331774319
Test: atest -c NexusLauncherTests:com.android.quickstep.TaplStartLauncherViaGestureTests
atest -c NexusLauncherTests:com.android.quickstep.util.SplitSelectStateControllerTest

Change-Id: I68ffcc4114644e75f751632eca8bc73e406139a8
parent 03c55c55
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import android.window.RemoteTransition;
import android.window.TransitionInfo;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.internal.logging.InstanceId;
import com.android.launcher3.Launcher;
@@ -132,6 +133,7 @@ public class SplitSelectStateController {
    private final StatsLogManager mStatsLogManager;
    private final SystemUiProxy mSystemUiProxy;
    private final StateManager mStateManager;
    @Nullable
    private SplitFromDesktopController mSplitFromDesktopController;
    @Nullable
    private DepthController mDepthController;
@@ -208,6 +210,9 @@ public class SplitSelectStateController {
        mActivityBackCallback = null;
        mAppPairsController.onDestroy();
        mSplitSelectDataHolder.onDestroy();
        if (mSplitFromDesktopController != null) {
            mSplitFromDesktopController.onDestroy();
        }
    }

    /**
@@ -643,7 +648,12 @@ public class SplitSelectStateController {
    }

    public void initSplitFromDesktopController(Launcher launcher) {
        mSplitFromDesktopController = new SplitFromDesktopController(launcher);
        initSplitFromDesktopController(new SplitFromDesktopController(launcher));
    }

    @VisibleForTesting
    void initSplitFromDesktopController(SplitFromDesktopController controller) {
        mSplitFromDesktopController = controller;
    }

    private RemoteTransition getShellRemoteTransition(int firstTaskId, int secondTaskId,
@@ -977,6 +987,11 @@ public class SplitSelectStateController {
            SystemUiProxy.INSTANCE.get(mLauncher).registerSplitSelectListener(mSplitSelectListener);
        }

        void onDestroy() {
            SystemUiProxy.INSTANCE.get(mLauncher).unregisterSplitSelectListener(
                    mSplitSelectListener);
        }

        /**
         * Enter split select from desktop mode.
         * @param taskInfo the desktop task to move to split stage
+14 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.quickstep.RecentsModel
import com.android.quickstep.SystemUiProxy
import com.android.quickstep.util.SplitSelectStateController.SplitFromDesktopController
import com.android.systemui.shared.recents.model.Task
import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
import java.util.function.Consumer
@@ -65,6 +66,7 @@ class SplitSelectStateControllerTest {
    private val context: StatefulActivity<*> = mock()
    private val recentsModel: RecentsModel = mock()
    private val pendingIntent: PendingIntent = mock()
    private val splitFromDesktopController: SplitFromDesktopController = mock()

    private lateinit var splitSelectStateController: SplitSelectStateController

@@ -607,6 +609,18 @@ class SplitSelectStateControllerTest {
        assertTrue(splitSelectStateController.isBothSplitAppsConfirmed)
    }

    @Test
    fun splitSelectStateControllerDestroyed_SplitFromDesktopControllerAlsoDestroyed() {
        // Initiate split from desktop controller
        splitSelectStateController.initSplitFromDesktopController(splitFromDesktopController)

        // Simulate default controller being destroyed
        splitSelectStateController.onDestroy()

        // Verify desktop controller is also destroyed
        verify(splitFromDesktopController).onDestroy()
    }

    // Generate GroupTask with default userId.
    private fun generateGroupTask(
        task1ComponentName: ComponentName,