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