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.wm.shell.desktopmode.compatui
18 
19 import android.os.Binder
20 import android.testing.AndroidTestingRunner
21 import android.view.SurfaceControl
22 import android.view.WindowManager.TRANSIT_CHANGE
23 import android.view.WindowManager.TRANSIT_CLOSE
24 import android.view.WindowManager.TRANSIT_OPEN
25 import androidx.test.filters.SmallTest
26 import com.android.wm.shell.ShellTestCase
27 import com.android.wm.shell.common.ShellExecutor
28 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
29 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTaskBuilder
30 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSystemModalTask
31 import com.android.wm.shell.desktopmode.DesktopRepository
32 import com.android.wm.shell.desktopmode.DesktopUserRepositories
33 import com.android.wm.shell.sysui.ShellInit
34 import com.android.wm.shell.transition.TransitionInfoBuilder
35 import com.android.wm.shell.transition.Transitions
36 import com.google.common.truth.Truth.assertThat
37 import org.junit.Before
38 import org.junit.Test
39 import org.junit.runner.RunWith
40 import org.mockito.ArgumentMatchers.anyInt
41 import org.mockito.kotlin.any
42 import org.mockito.kotlin.mock
43 import org.mockito.kotlin.verify
44 import org.mockito.kotlin.whenever
45 
46 /**
47  * Tests for {@link SystemModalsTransitionHandler}
48  * Usage: atest WMShellUnitTests:SystemModalsTransitionHandlerTest
49  */
50 @SmallTest
51 @RunWith(AndroidTestingRunner::class)
52 class SystemModalsTransitionHandlerTest : ShellTestCase() {
53     private val mainExecutor = mock<ShellExecutor>()
54     private val animExecutor = mock<ShellExecutor>()
55     private val shellInit = mock<ShellInit>()
56     private val transitions = mock<Transitions>()
57     private val desktopUserRepositories = mock<DesktopUserRepositories>()
58     private val desktopRepository = mock<DesktopRepository>()
59     private val startT = mock<SurfaceControl.Transaction>()
60     private val finishT = mock<SurfaceControl.Transaction>()
61 
62     private lateinit var transitionHandler: SystemModalsTransitionHandler
63 
64     @Before
setUpnull65     fun setUp() {
66         // Simulate having one Desktop task so that we see Desktop Mode as active
67         whenever(desktopUserRepositories.current).thenReturn(desktopRepository)
68         whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
69         transitionHandler = createTransitionHandler()
70     }
71 
createTransitionHandlernull72     private fun createTransitionHandler() =
73         SystemModalsTransitionHandler(
74             context,
75             mainExecutor,
76             animExecutor,
77             shellInit,
78             transitions,
79             desktopUserRepositories,
80         )
81 
82     @Test
83     fun instantiate_addsInitCallback() {
84         verify(shellInit).addInitCallback(any(), any<SystemModalsTransitionHandler>())
85     }
86 
87     @Test
startAnimation_desktopNotActive_doesNotAnimatenull88     fun startAnimation_desktopNotActive_doesNotAnimate() {
89         whenever(desktopUserRepositories.current.getVisibleTaskCount(anyInt())).thenReturn(1)
90         val info =
91             TransitionInfoBuilder(TRANSIT_OPEN)
92                 .addChange(TRANSIT_OPEN, createSystemModalTask())
93                 .build()
94 
95         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
96     }
97 
98     @Test
startAnimation_launchingSystemModal_animatesnull99     fun startAnimation_launchingSystemModal_animates() {
100         val info =
101             TransitionInfoBuilder(TRANSIT_OPEN)
102                 .addChange(TRANSIT_OPEN, createSystemModalTask())
103                 .build()
104 
105         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
106     }
107 
108     @Test
startAnimation_nonLaunchingSystemModal_doesNotAnimatenull109     fun startAnimation_nonLaunchingSystemModal_doesNotAnimate() {
110         val info =
111             TransitionInfoBuilder(TRANSIT_OPEN)
112                 .addChange(TRANSIT_CHANGE, createSystemModalTask())
113                 .build()
114 
115         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
116     }
117 
118     @Test
startAnimation_launchingFullscreenTask_doesNotAnimatenull119     fun startAnimation_launchingFullscreenTask_doesNotAnimate() {
120         val info =
121             TransitionInfoBuilder(TRANSIT_OPEN)
122                 .addChange(TRANSIT_OPEN, createFullscreenTask())
123                 .build()
124 
125         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
126     }
127 
128     @Test
startAnimation_closingSystemModal_animatesnull129     fun startAnimation_closingSystemModal_animates() {
130         val info =
131             TransitionInfoBuilder(TRANSIT_CLOSE)
132                 .addChange(TRANSIT_CLOSE, createSystemModalTask())
133                 .build()
134 
135         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
136     }
137 
138     @Test
startAnimation_closingFullscreenTask_doesNotAnimatenull139     fun startAnimation_closingFullscreenTask_doesNotAnimate() {
140         val info =
141             TransitionInfoBuilder(TRANSIT_CLOSE)
142                 .addChange(TRANSIT_CLOSE, createFullscreenTask())
143                 .build()
144 
145         assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
146     }
147 
148     @Test
startAnimation_closingPreviouslyLaunchedSystemModal_animatesnull149     fun startAnimation_closingPreviouslyLaunchedSystemModal_animates() {
150         val systemModalTask = createSystemModalTask()
151         val nonModalSystemModalTask =
152             createFullscreenTaskBuilder().setTaskId(systemModalTask.taskId).build()
153         val launchInfo =
154             TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, systemModalTask).build()
155         transitionHandler.startAnimation(Binder(), launchInfo, startT, finishT) {}
156         val closeInfo =
157             TransitionInfoBuilder(TRANSIT_CLOSE)
158                 .addChange(TRANSIT_CLOSE, nonModalSystemModalTask)
159                 .build()
160 
161         assertThat(transitionHandler.startAnimation(Binder(), closeInfo, startT, finishT) {})
162             .isTrue()
163     }
164 }
165