1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.desktop
18 
19 import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
20 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
21 import android.content.Context
22 import android.platform.test.annotations.DisableFlags
23 import android.platform.test.annotations.EnableFlags
24 import android.platform.test.flag.junit.SetFlagsRule
25 import android.view.WindowManager.TRANSIT_OPEN
26 import android.view.WindowManager.TRANSIT_TO_FRONT
27 import android.window.TransitionFilter
28 import androidx.test.ext.junit.runners.AndroidJUnit4
29 import androidx.test.filters.SmallTest
30 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
31 import com.android.quickstep.SystemUiProxy
32 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS
33 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX
34 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
35 import com.google.common.truth.Truth.assertThat
36 import org.junit.After
37 import org.junit.Before
38 import org.junit.Rule
39 import org.junit.Test
40 import org.junit.runner.RunWith
41 import org.mockito.kotlin.any
42 import org.mockito.kotlin.argumentCaptor
43 import org.mockito.kotlin.mock
44 import org.mockito.kotlin.times
45 import org.mockito.kotlin.verify
46 import org.mockito.kotlin.whenever
47 import org.mockito.quality.Strictness
48 
49 @SmallTest
50 @RunWith(AndroidJUnit4::class)
51 class DesktopAppLaunchTransitionManagerTest {
52 
53     @get:Rule val mSetFlagsRule = SetFlagsRule()
54 
55     private val mockitoSession =
56         mockitoSession()
57             .strictness(Strictness.LENIENT)
58             .mockStatic(DesktopModeStatus::class.java)
59             .startMocking()
60 
61     private val context = mock<Context>()
62     private val systemUiProxy = mock<SystemUiProxy>()
63     private lateinit var transitionManager: DesktopAppLaunchTransitionManager
64 
65     @Before
setUpnull66     fun setUp() {
67         whenever(context.resources).thenReturn(mock())
68         whenever(DesktopModeStatus.canEnterDesktopMode(context)).thenReturn(true)
69         transitionManager = DesktopAppLaunchTransitionManager(context, systemUiProxy)
70     }
71 
72     @After
tearDownnull73     fun tearDown() {
74         mockitoSession.finishMocking()
75     }
76 
77     @Test
78     @EnableFlags(
79         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS,
80         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX,
81     )
registerTransitions_appLaunchFlagEnabled_registersTransitionnull82     fun registerTransitions_appLaunchFlagEnabled_registersTransition() {
83         transitionManager.registerTransitions()
84 
85         verify(systemUiProxy, times(1)).registerRemoteTransition(any(), any())
86     }
87 
88     @Test
89     @DisableFlags(
90         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS,
91         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX,
92     )
registerTransitions_appLaunchFlagDisabled_doesntRegisterTransitionnull93     fun registerTransitions_appLaunchFlagDisabled_doesntRegisterTransition() {
94         transitionManager.registerTransitions()
95 
96         verify(systemUiProxy, times(0)).registerRemoteTransition(any(), any())
97     }
98 
99     @Test
100     @EnableFlags(
101         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS,
102         FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX,
103     )
registerTransitions_usesCorrectFilternull104     fun registerTransitions_usesCorrectFilter() {
105         transitionManager.registerTransitions()
106         val filterArgumentCaptor = argumentCaptor<TransitionFilter>()
107 
108         verify(systemUiProxy, times(1))
109             .registerRemoteTransition(any(), filterArgumentCaptor.capture())
110 
111         assertThat(filterArgumentCaptor.lastValue).isNotNull()
112         assertThat(filterArgumentCaptor.lastValue.mTypeSet)
113             .isEqualTo(intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT))
114         assertThat(filterArgumentCaptor.lastValue.mRequirements).hasLength(1)
115         val launchRequirement = filterArgumentCaptor.lastValue.mRequirements!![0]
116         assertThat(launchRequirement.mModes).isEqualTo(intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT))
117         assertThat(launchRequirement.mActivityType).isEqualTo(ACTIVITY_TYPE_STANDARD)
118         assertThat(launchRequirement.mWindowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
119     }
120 }
121