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

Commit 7829a1ce authored by Tony Wickham's avatar Tony Wickham
Browse files

Only commitRunningAppsToUI if shownTasks changed

- Add GroupTask and DesktopTask equals() (with tests)
- Add tests to verify multiple onRecentTasksChanged
  doesn't commitRunningAppsToUI if there's no change
- Add tests to verify commitRunningAppsToUI is still
  called if minimized or running apps set changes

Bug: 348802109
Bug: 348787176
Test: TaskbarRecentAppsControllerTest
Test: GroupTaskTest
Test: log TaskbarView#onMeasure() locally, ensure it is called
much less despite noisy onRecentTasksChanged callbacks
Flag: com.android.window.flags.enable_desktop_windowing_taskbar_running_apps

Change-Id: I3efff7f4492272f88aa2bdbd7cc45bd2bf8156f6
parent 9f8e1471
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -149,20 +149,39 @@ class TaskbarRecentAppsController(
            taskListChangeId =
                recentsModel.getTasks { tasks ->
                    allRecentTasks = tasks
                    val oldRunningPackages = runningAppPackages
                    val oldMinimizedPackages = minimizedAppPackages
                    desktopTask = allRecentTasks.filterIsInstance<DesktopTask>().firstOrNull()
                    onRecentsOrHotseatChanged()
                    val runningPackagesChanged = oldRunningPackages != runningAppPackages
                    val minimizedPackagessChanged = oldMinimizedPackages != minimizedAppPackages
                    if (
                        onRecentsOrHotseatChanged() ||
                            runningPackagesChanged ||
                            minimizedPackagessChanged
                    ) {
                        controllers.taskbarViewController.commitRunningAppsToUI()
                    }
                }
        }
    }

    private fun onRecentsOrHotseatChanged() {
    /**
     * Updates [shownTasks] when Recents or Hotseat changes.
     *
     * @return Whether [shownTasks] changed.
     */
    private fun onRecentsOrHotseatChanged(): Boolean {
        val oldShownTasks = shownTasks
        shownTasks =
            if (isInDesktopMode) {
                computeShownRunningTasks()
            } else {
                computeShownRecentTasks()
            }
        val shownTasksChanged = oldShownTasks != shownTasks
        if (!shownTasksChanged) {
            return shownTasksChanged
        }

        for (groupTask in shownTasks) {
            for (task in groupTask.tasks) {
@@ -174,6 +193,7 @@ class TaskbarRecentAppsController(
                }
            }
        }
        return shownTasksChanged
    }

    private fun computeShownRunningTasks(): List<GroupTask> {
+13 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;

import java.util.List;
import java.util.Objects;

/**
 * A {@link Task} container that can contain N number of tasks that are part of the desktop in
@@ -68,4 +69,16 @@ public class DesktopTask extends GroupTask {
        return "type=" + taskViewType + " tasks=" + tasks;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DesktopTask that)) return false;
        if (!super.equals(o)) return false;
        return Objects.equals(tasks, that.tasks);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), tasks);
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.shared.recents.model.Task;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * A {@link Task} container that can contain one or two tasks, depending on if the two tasks
@@ -91,4 +92,17 @@ public class GroupTask {
        return "type=" + taskViewType + " task1=" + task1 + " task2=" + task2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof GroupTask that)) return false;
        return taskViewType == that.taskViewType && Objects.equals(task1,
                that.task1) && Objects.equals(task2, that.task2)
                && Objects.equals(mSplitBounds, that.mSplitBounds);
    }

    @Override
    public int hashCode() {
        return Objects.hash(task1, task2, mSplitBounds, taskViewType);
    }
}
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.quickstep.util

import android.content.ComponentName
import android.content.Intent
import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.systemui.shared.recents.model.Task
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(LauncherMultivalentJUnit::class)
class DesktopTaskTest {

    @Test
    fun testDesktopTask_sameInstance_isEqual() {
        val task = DesktopTask(createTasks(1))
        assertThat(task).isEqualTo(task)
    }

    @Test
    fun testDesktopTask_identicalConstructor_isEqual() {
        val task1 = DesktopTask(createTasks(1))
        val task2 = DesktopTask(createTasks(1))
        assertThat(task1).isEqualTo(task2)
    }

    @Test
    fun testDesktopTask_copy_isEqual() {
        val task1 = DesktopTask(createTasks(1))
        val task2 = task1.copy()
        assertThat(task1).isEqualTo(task2)
    }

    @Test
    fun testDesktopTask_differentId_isNotEqual() {
        val task1 = DesktopTask(createTasks(1))
        val task2 = DesktopTask(createTasks(2))
        assertThat(task1).isNotEqualTo(task2)
    }

    @Test
    fun testDesktopTask_differentLength_isNotEqual() {
        val task1 = DesktopTask(createTasks(1))
        val task2 = DesktopTask(createTasks(1, 2))
        assertThat(task1).isNotEqualTo(task2)
    }

    private fun createTasks(vararg ids: Int): List<Task> {
        return ids.map { Task(Task.TaskKey(it, 0, Intent(), ComponentName("", ""), 0, 0)) }
    }
}
+109 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.quickstep.util

import android.content.ComponentName
import android.content.Intent
import android.graphics.Rect
import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.quickstep.views.TaskView
import com.android.systemui.shared.recents.model.Task
import com.android.wm.shell.common.split.SplitScreenConstants
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(LauncherMultivalentJUnit::class)
class GroupTaskTest {

    @Test
    fun testGroupTask_sameInstance_isEqual() {
        val task = GroupTask(createTask(1))
        assertThat(task).isEqualTo(task)
    }

    @Test
    fun testGroupTask_identicalConstructor_isEqual() {
        val task1 = GroupTask(createTask(1))
        val task2 = GroupTask(createTask(1))
        assertThat(task1).isEqualTo(task2)
    }

    @Test
    fun testGroupTask_copy_isEqual() {
        val task1 = GroupTask(createTask(1))
        val task2 = task1.copy()
        assertThat(task1).isEqualTo(task2)
    }

    @Test
    fun testGroupTask_differentId_isNotEqual() {
        val task1 = GroupTask(createTask(1))
        val task2 = GroupTask(createTask(2))
        assertThat(task1).isNotEqualTo(task2)
    }

    @Test
    fun testGroupTask_equalSplitTasks_isEqual() {
        val splitBounds =
            SplitConfigurationOptions.SplitBounds(
                Rect(),
                Rect(),
                1,
                2,
                SplitScreenConstants.SNAP_TO_50_50
            )
        val task1 = GroupTask(createTask(1), createTask(2), splitBounds, TaskView.Type.GROUPED)
        val task2 = GroupTask(createTask(1), createTask(2), splitBounds, TaskView.Type.GROUPED)
        assertThat(task1).isEqualTo(task2)
    }

    @Test
    fun testGroupTask_differentSplitTasks_isNotEqual() {
        val splitBounds1 =
            SplitConfigurationOptions.SplitBounds(
                Rect(),
                Rect(),
                1,
                2,
                SplitScreenConstants.SNAP_TO_50_50
            )
        val splitBounds2 =
            SplitConfigurationOptions.SplitBounds(
                Rect(),
                Rect(),
                1,
                2,
                SplitScreenConstants.SNAP_TO_30_70
            )
        val task1 = GroupTask(createTask(1), createTask(2), splitBounds1, TaskView.Type.GROUPED)
        val task2 = GroupTask(createTask(1), createTask(2), splitBounds2, TaskView.Type.GROUPED)
        assertThat(task1).isNotEqualTo(task2)
    }

    @Test
    fun testGroupTask_differentType_isNotEqual() {
        val task1 = GroupTask(createTask(1), null, null, TaskView.Type.SINGLE)
        val task2 = GroupTask(createTask(1), null, null, TaskView.Type.DESKTOP)
        assertThat(task1).isNotEqualTo(task2)
    }

    private fun createTask(id: Int): Task {
        return Task(Task.TaskKey(id, 0, Intent(), ComponentName("", ""), 0, 0))
    }
}
Loading