Merge "Refactor SplitSelectStateController to add testing" into tm-qpr-dev

This commit is contained in:
Vinit Nayak
2023-02-22 21:45:42 +00:00
committed by Android (Google) Code Review
4 changed files with 220 additions and 5 deletions

View File

@@ -235,7 +235,8 @@ public class QuickstepLauncher extends Launcher {
RecentsView overviewPanel = getOverviewPanel();
mSplitSelectStateController =
new SplitSelectStateController(this, mHandler, getStateManager(),
getDepthController(), getStatsLogManager());
getDepthController(), getStatsLogManager(),
SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this));
overviewPanel.init(mActionsView, mSplitSelectStateController);
mSplitWithKeyboardShortcutController = new SplitWithKeyboardShortcutController(this,
mSplitSelectStateController);

View File

@@ -134,7 +134,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
SplitSelectStateController controller =
new SplitSelectStateController(this, mHandler, getStateManager(),
/* depthController */ null, getStatsLogManager());
null /* depthController */, getStatsLogManager(),
SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this));
mDragLayer.recreateControllers();
mFallbackRecentsView.init(mActionsView, controller);

View File

@@ -107,14 +107,15 @@ public class SplitSelectStateController {
private FloatingTaskView mFirstFloatingTaskView;
public SplitSelectStateController(Context context, Handler handler, StateManager stateManager,
DepthController depthController, StatsLogManager statsLogManager) {
DepthController depthController, StatsLogManager statsLogManager,
SystemUiProxy systemUiProxy, RecentsModel recentsModel) {
mContext = context;
mHandler = handler;
mStatsLogManager = statsLogManager;
mSystemUiProxy = SystemUiProxy.INSTANCE.get(mContext);
mSystemUiProxy = systemUiProxy;
mStateManager = stateManager;
mDepthController = depthController;
mRecentTasksModel = RecentsModel.INSTANCE.get(context);
mRecentTasksModel = recentsModel;
}
/**

View File

@@ -0,0 +1,212 @@
/*
* Copyright (C) 2023 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.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Handler
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.launcher3.LauncherState
import com.android.launcher3.logging.StatsLogManager
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.statehandlers.DepthController
import com.android.launcher3.statemanager.StateManager
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.launcher3.util.withArgCaptor
import com.android.quickstep.RecentsModel
import com.android.quickstep.SystemUiProxy
import com.android.systemui.shared.recents.model.Task
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.ArrayList
import java.util.function.Consumer
@RunWith(AndroidJUnit4::class)
class SplitSelectStateControllerTest {
@Mock lateinit var systemUiProxy: SystemUiProxy
@Mock lateinit var depthController: DepthController
@Mock lateinit var statsLogManager: StatsLogManager
@Mock lateinit var stateManager: StateManager<LauncherState>
@Mock lateinit var handler: Handler
@Mock lateinit var context: Context
@Mock lateinit var recentsModel: RecentsModel
lateinit var splitSelectStateController: SplitSelectStateController
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
splitSelectStateController = SplitSelectStateController(context, handler,
stateManager, depthController, statsLogManager, systemUiProxy, recentsModel)
}
@Test
fun activeTasks_noMatchingTasks() {
val groupTask1 = generateGroupTask(
ComponentName("pomegranate", "juice"),
ComponentName("pumpkin", "pie"))
val groupTask2 = generateGroupTask(
ComponentName("hotdog", "juice"),
ComponentName("personal", "computer"))
val tasks: ArrayList<GroupTask> = ArrayList()
tasks.add(groupTask1)
tasks.add(groupTask2)
// Assertions happen in the callback we get from what we pass into
// #findLastActiveTaskAndRunCallback
val taskConsumer = Consumer<Task> {
assertNull("No tasks should have matched", it /*task*/)
}
// Capture callback from recentsModel#getTasks()
val consumer = withArgCaptor<Consumer<ArrayList<GroupTask>>> {
splitSelectStateController.findLastActiveTaskAndRunCallback(
ComponentName("no", "match"), taskConsumer)
verify(recentsModel).getTasks(capture())
}
// Send our mocked tasks
consumer.accept(tasks)
}
@Test
fun activeTasks_singleMatchingTask() {
val matchingPackage = "hotdog"
val matchingClass = "juice"
val groupTask1 = generateGroupTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pomegranate", "juice"))
val groupTask2 = generateGroupTask(
ComponentName("pumpkin", "pie"),
ComponentName("personal", "computer"))
val tasks: ArrayList<GroupTask> = ArrayList()
tasks.add(groupTask1)
tasks.add(groupTask2)
// Assertions happen in the callback we get from what we pass into
// #findLastActiveTaskAndRunCallback
val taskConsumer = Consumer<Task> {
assertEquals("ComponentName package mismatched",
it.key.baseIntent.component.packageName, matchingPackage)
assertEquals("ComponentName class mismatched",
it.key.baseIntent.component.className, matchingClass)
assertEquals(it, groupTask1.task1)
}
// Capture callback from recentsModel#getTasks()
val consumer = withArgCaptor<Consumer<ArrayList<GroupTask>>> {
splitSelectStateController.findLastActiveTaskAndRunCallback(
ComponentName(matchingPackage, matchingClass), taskConsumer)
verify(recentsModel).getTasks(capture())
}
// Send our mocked tasks
consumer.accept(tasks)
}
@Test
fun activeTasks_multipleMatchMostRecentTask() {
val matchingPackage = "hotdog"
val matchingClass = "juice"
val groupTask1 = generateGroupTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pumpkin", "pie"))
val groupTask2 = generateGroupTask(
ComponentName("pomegranate", "juice"),
ComponentName(matchingPackage, matchingClass))
val tasks: ArrayList<GroupTask> = ArrayList()
tasks.add(groupTask2)
tasks.add(groupTask1)
// Assertions happen in the callback we get from what we pass into
// #findLastActiveTaskAndRunCallback
val taskConsumer = Consumer<Task> {
assertEquals("ComponentName package mismatched",
it.key.baseIntent.component.packageName, matchingPackage)
assertEquals("ComponentName class mismatched",
it.key.baseIntent.component.className, matchingClass)
assertEquals(it, groupTask2.task2)
}
// Capture callback from recentsModel#getTasks()
val consumer = withArgCaptor<Consumer<ArrayList<GroupTask>>> {
splitSelectStateController.findLastActiveTaskAndRunCallback(
ComponentName(matchingPackage, matchingClass), taskConsumer)
verify(recentsModel).getTasks(capture())
}
// Send our mocked tasks
consumer.accept(tasks)
}
@Test
fun setInitialApp_withTaskId() {
splitSelectStateController.setInitialTaskSelect(null /*intent*/,
-1 /*stagePosition*/, ItemInfo(), null /*splitEvent*/, 10 /*alreadyRunningTask*/)
assertTrue(splitSelectStateController.isSplitSelectActive)
}
@Test
fun setInitialApp_withIntent() {
splitSelectStateController.setInitialTaskSelect(Intent() /*intent*/,
-1 /*stagePosition*/, ItemInfo(), null /*splitEvent*/, -1 /*alreadyRunningTask*/)
assertTrue(splitSelectStateController.isSplitSelectActive)
}
@Test
fun resetAfterInitial() {
splitSelectStateController.setInitialTaskSelect(Intent() /*intent*/,
-1 /*stagePosition*/, ItemInfo(), null /*splitEvent*/,
-1)
splitSelectStateController.resetState()
assertFalse(splitSelectStateController.isSplitSelectActive)
}
private fun generateGroupTask(task1ComponentName: ComponentName,
task2ComponentName: ComponentName): GroupTask {
val task1 = Task()
var taskInfo = ActivityManager.RunningTaskInfo()
var intent = Intent()
intent.component = task1ComponentName
taskInfo.baseIntent = intent
task1.key = Task.TaskKey(taskInfo)
val task2 = Task()
taskInfo = ActivityManager.RunningTaskInfo()
intent = Intent()
intent.component = task2ComponentName
taskInfo.baseIntent = intent
task2.key = Task.TaskKey(taskInfo)
return GroupTask(task1, task2, SplitConfigurationOptions.SplitBounds(
Rect(), Rect(), -1, -1
))
}
}