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

Commit 3ce64d59 authored by Jeremy Sim's avatar Jeremy Sim Committed by Android (Google) Code Review
Browse files

Merge "Add unit tests for SplitSelectDataHolder" into udc-qpr-dev

parents fee828cd a8690f5e
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -45,7 +45,11 @@ import java.io.PrintWriter
 *
 * After setting the correct fields for initial/second.* variables, this converts them into the
 * correct [PendingIntent] and [ShortcutInfo] objects where applicable and sends the necessary
 * data back via [getSplitLaunchData].
 * data back via [getSplitLaunchData]. Note: there should be only one "initial" field and one
 * "second" field set, with the rest remaining null. (Exception: [Intent] and [UserHandle] are
 * always passed in together as a set, and are converted to a single [PendingIntent] or
 * [ShortcutInfo]+[PendingIntent] before launch.)
 *
 * [SplitLaunchType] indicates the type of tasks/apps/intents being launched given the provided
 * state
 */
@@ -80,21 +84,21 @@ class SplitSelectDataHolder(
        const val SPLIT_SINGLE_SHORTCUT_FULLSCREEN = 8
    }


    @StagePosition
    private var initialStagePosition: Int = STAGE_POSITION_UNDEFINED
    private var itemInfo: ItemInfo? = null
    private var splitEvent: EventEnum? = null

    private var initialTaskId: Int = INVALID_TASK_ID
    private var secondTaskId: Int = INVALID_TASK_ID
    private var initialUser: UserHandle? = null
    private var secondUser: UserHandle? = null
    private var initialIntent: Intent? = null
    private var secondIntent: Intent? = null
    private var initialUser: UserHandle? = null
    private var secondUser: UserHandle? = null
    private var initialPendingIntent: PendingIntent? = null
    private var secondPendingIntent: PendingIntent? = null
    private var itemInfo: ItemInfo? = null
    private var splitEvent: EventEnum? = null
    private var initialShortcut: ShortcutInfo? = null
    private var secondShortcut: ShortcutInfo? = null
    private var initialPendingIntent: PendingIntent? = null

    /**
     * @param alreadyRunningTask if set to [android.app.ActivityTaskManager.INVALID_TASK_ID]
@@ -217,7 +221,7 @@ class SplitSelectDataHolder(
     *   split task in fullscreen
     */
    fun getFullscreenLaunchData() : SplitLaunchData {
        // Convert all intents to shortcut infos to see if determine if we launch shortcut or intent
        // Convert all intents to shortcut infos to determine if we launch shortcut or intent
        convertIntentsToFinalTypes()
        val splitLaunchType = getFullscreenLaunchType()

+395 −0
Original line number Diff line number Diff line
/*
 *  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.RunningTaskInfo
import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.os.UserHandle
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.ui.AbstractLauncherUiTest
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_PENDINGINTENT_PENDINGINTENT
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_PENDINGINTENT_TASK
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_SHORTCUT_TASK
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_SINGLE_INTENT_FULLSCREEN
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_SINGLE_SHORTCUT_FULLSCREEN
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_SINGLE_TASK_FULLSCREEN
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_TASK_PENDINGINTENT
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_TASK_SHORTCUT
import com.android.quickstep.util.SplitSelectDataHolder.Companion.SPLIT_TASK_TASK
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

class SplitSelectDataHolderTest {
    private lateinit var splitSelectDataHolder: SplitSelectDataHolder

    private val context: Context =
        ContextWrapper(InstrumentationRegistry.getInstrumentation().targetContext)
    private val sampleTaskInfo = RunningTaskInfo()
    private val sampleTaskId = 10
    private val sampleTaskId2 = 11
    private val sampleUser = UserHandle(0)
    private val sampleIntent = Intent()
    private val sampleIntent2 = Intent()
    private val sampleShortcut = Intent()
    private val sampleShortcut2 = Intent()
    private val sampleItemInfo = ItemInfo()
    private val samplePackage =
        AbstractLauncherUiTest.resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)

    @Before
    fun setup() {
        splitSelectDataHolder = SplitSelectDataHolder(context)

        sampleTaskInfo.taskId = sampleTaskId
        sampleItemInfo.user = sampleUser
        sampleIntent.setPackage(samplePackage)
        sampleIntent2.setPackage(samplePackage)
        sampleShortcut.setPackage(samplePackage)
        sampleShortcut2.setPackage(samplePackage)
        sampleShortcut.putExtra(ShortcutKey.EXTRA_SHORTCUT_ID, "sampleShortcut")
        sampleShortcut2.putExtra(ShortcutKey.EXTRA_SHORTCUT_ID, "sampleShortcut2")
    }

    @Test
    fun setInitialAsTask() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            null,
            null
        )
        assertTrue(splitSelectDataHolder.isSplitSelectActive())
    }

    @Test
    fun setInitialAsIntent() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        assertTrue(splitSelectDataHolder.isSplitSelectActive())
    }

    @Test
    fun setInitialAsIntentWithAlreadyRunningTask() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            sampleTaskId
        )
        assertTrue(splitSelectDataHolder.isSplitSelectActive())
    }

    @Test
    fun setInitialAsShortcut() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleShortcut,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        assertTrue(splitSelectDataHolder.isSplitSelectActive())
    }

    @Test
    fun setSecondAsTask() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleShortcut,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        splitSelectDataHolder.setSecondTask(sampleTaskId)
        assertTrue(splitSelectDataHolder.isBothSplitAppsConfirmed())
    }

    @Test
    fun setSecondAsIntent() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            null,
            null
        )
        splitSelectDataHolder.setSecondTask(sampleIntent, sampleUser)
        assertTrue(splitSelectDataHolder.isBothSplitAppsConfirmed())
    }

    @Test
    fun setSecondAsShortcut() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        splitSelectDataHolder.setSecondTask(sampleShortcut, sampleUser)
        assertTrue(splitSelectDataHolder.isBothSplitAppsConfirmed())
    }

    @Test
    fun generateLaunchData_Task_Task() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null
        )
        splitSelectDataHolder.setSecondTask(sampleTaskId2)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_TASK_TASK)

        // should contain a valid task ID for first app, and no intent or shortcut
        assertNotEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialPendingIntent)
        assertNull(launchData.initialShortcut)

        // should contain a valid task ID for second app, and no intent or shortcut
        assertNotEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Task_Intent() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null
        )
        splitSelectDataHolder.setSecondTask(sampleIntent, sampleUser)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_TASK_PENDINGINTENT)

        // should contain a valid task ID for first app, and no intent or shortcut
        assertNotEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialPendingIntent)
        assertNull(launchData.initialShortcut)

        // should contain a valid intent for second app, and no task ID or shortcut
        assertNotNull(launchData.secondPendingIntent)
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Task_Shortcut() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null
        )
        splitSelectDataHolder.setSecondTask(sampleShortcut, sampleUser)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_TASK_SHORTCUT)

        // should contain a valid task ID for first app, and no intent or shortcut
        assertNotEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialPendingIntent)
        assertNull(launchData.initialShortcut)

        // should contain a valid shortcut and intent for second app, and no task ID
        assertNotNull(launchData.secondShortcut)
        assertNotNull(launchData.secondPendingIntent)
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
    }

    @Test
    fun generateLaunchData_Intent_Task() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        splitSelectDataHolder.setSecondTask(sampleTaskId)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_PENDINGINTENT_TASK)

        // should contain a valid intent for first app, and no task ID or shortcut
        assertNotNull(launchData.initialPendingIntent)
        assertEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialShortcut)

        // should contain a valid task ID for second app, and no intent or shortcut
        assertNotEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Shortcut_Task() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleShortcut,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        splitSelectDataHolder.setSecondTask(sampleTaskId)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_SHORTCUT_TASK)

        // should contain a valid shortcut and intent for first app, and no task ID
        assertNotNull(launchData.initialShortcut)
        assertNotNull(launchData.initialPendingIntent)
        assertEquals(launchData.initialTaskId, INVALID_TASK_ID)

        // should contain a valid task ID for second app, and no intent or shortcut
        assertNotEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Intent_Intent() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        splitSelectDataHolder.setSecondTask(sampleIntent2, sampleUser)
        val launchData = splitSelectDataHolder.getSplitLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_PENDINGINTENT_PENDINGINTENT)

        // should contain a valid intent for first app, and no task ID or shortcut
        assertNotNull(launchData.initialPendingIntent)
        assertEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialShortcut)

        // should contain a valid intent for second app, and no task ID or shortcut
        assertNotNull(launchData.secondPendingIntent)
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Single_Task() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null
        )
        val launchData = splitSelectDataHolder.getFullscreenLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_SINGLE_TASK_FULLSCREEN)

        // should contain a valid task ID for first app, and no intent or shortcut
        assertNotEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialPendingIntent)
        assertNull(launchData.initialShortcut)

        // should contain no task ID, intent, or shortcut for second app
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Single_Intent() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleIntent,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        val launchData = splitSelectDataHolder.getFullscreenLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_SINGLE_INTENT_FULLSCREEN)

        // should contain a valid intent for first app, and no task ID or shortcut
        assertNotNull(launchData.initialPendingIntent)
        assertEquals(launchData.initialTaskId, INVALID_TASK_ID)
        assertNull(launchData.initialShortcut)

        // should contain no task ID, intent, or shortcut for second app
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun generateLaunchData_Single_Shortcut() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleShortcut,
            STAGE_POSITION_TOP_OR_LEFT,
            sampleItemInfo,
            null,
            INVALID_TASK_ID
        )
        val launchData = splitSelectDataHolder.getFullscreenLaunchData()

        assertEquals(launchData.splitLaunchType, SPLIT_SINGLE_SHORTCUT_FULLSCREEN)

        // should contain a valid shortcut and intent for first app, and no task ID
        assertNotNull(launchData.initialShortcut)
        assertNotNull(launchData.initialPendingIntent)
        assertEquals(launchData.initialTaskId, INVALID_TASK_ID)

        // should contain no task ID, intent, or shortcut for second app
        assertEquals(launchData.secondTaskId, INVALID_TASK_ID)
        assertNull(launchData.secondPendingIntent)
        assertNull(launchData.secondShortcut)
    }

    @Test
    fun clearState() {
        splitSelectDataHolder.setInitialTaskSelect(
            sampleTaskInfo,
            STAGE_POSITION_TOP_OR_LEFT,
            null,
            null
        )
        splitSelectDataHolder.setSecondTask(sampleIntent, sampleUser)
        splitSelectDataHolder.resetState()
        assertFalse(splitSelectDataHolder.isSplitSelectActive())
    }
}