1 /*
2  * Copyright (C) 2023 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.server.wm;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20 
21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
23 
24 import static org.junit.Assert.assertEquals;
25 
26 import android.platform.test.annotations.Presubmit;
27 
28 import androidx.test.filters.SmallTest;
29 
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 import java.util.ArrayList;
35 
36 /**
37  * Test class for {@link ActivitySnapshotController}.
38  *
39  * Build/Install/Run:
40  *  *  atest WmTests:ActivitySnapshotControllerTests
41  */
42 @SmallTest
43 @Presubmit
44 @RunWith(WindowTestRunner.class)
45 public class ActivitySnapshotControllerTests extends WindowTestsBase {
46 
47     private ActivitySnapshotController mActivitySnapshotController;
48     @Before
setUp()49     public void setUp() throws Exception {
50         spyOn(mWm.mSnapshotController.mActivitySnapshotController);
51         mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
52         doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
53         mActivitySnapshotController.resetTmpFields();
54     }
55     @Test
testOpenActivityTransition()56     public void testOpenActivityTransition() {
57         final Task task = createTask(mDisplayContent);
58         // note for createAppWindow: the new child is added at index 0
59         final WindowState openingWindow = createAppWindow(task,
60                 ACTIVITY_TYPE_STANDARD, "openingWindow");
61         openingWindow.mActivityRecord.commitVisibility(
62                 true /* visible */, true /* performLayout */);
63         final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
64                 "closingWindow");
65         closingWindow.mActivityRecord.commitVisibility(
66                 false /* visible */, true /* performLayout */);
67         final ArrayList<WindowContainer> windows = new ArrayList<>();
68         windows.add(openingWindow.mActivityRecord);
69         windows.add(closingWindow.mActivityRecord);
70         mActivitySnapshotController.handleTransitionFinish(windows);
71 
72         assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
73         mActivitySnapshotController.resetTmpFields();
74 
75         // simulate three activity
76         final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
77                 "belowClose");
78         belowClose.mActivityRecord.commitVisibility(
79                 false /* visible */, true /* performLayout */);
80         windows.add(belowClose.mActivityRecord);
81         mActivitySnapshotController.handleTransitionFinish(windows);
82         assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
83         assertEquals(belowClose.mActivityRecord,
84                 mActivitySnapshotController.mPendingRemoveActivity.valueAt(0));
85     }
86 
87     @Test
testCloseActivityTransition()88     public void testCloseActivityTransition() {
89         final Task task = createTask(mDisplayContent);
90         // note for createAppWindow: the new child is added at index 0
91         final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
92                 "closingWindow");
93         closingWindow.mActivityRecord.commitVisibility(
94                 false /* visible */, true /* performLayout */);
95         final WindowState openingWindow = createAppWindow(task,
96                 ACTIVITY_TYPE_STANDARD, "openingWindow");
97         openingWindow.mActivityRecord.commitVisibility(
98                 true /* visible */, true /* performLayout */);
99         final ArrayList<WindowContainer> windows = new ArrayList<>();
100         windows.add(openingWindow.mActivityRecord);
101         windows.add(closingWindow.mActivityRecord);
102         mActivitySnapshotController.handleTransitionFinish(windows);
103         assertEquals(1, mActivitySnapshotController.mPendingDeleteActivity.size());
104         assertEquals(openingWindow.mActivityRecord,
105                 mActivitySnapshotController.mPendingDeleteActivity.valueAt(0));
106         mActivitySnapshotController.resetTmpFields();
107 
108         // simulate three activity
109         final WindowState belowOpen = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
110                 "belowOpen");
111         belowOpen.mActivityRecord.commitVisibility(
112                 false /* visible */, true /* performLayout */);
113         windows.add(belowOpen.mActivityRecord);
114         mActivitySnapshotController.handleTransitionFinish(windows);
115         assertEquals(1, mActivitySnapshotController.mPendingDeleteActivity.size());
116         assertEquals(1, mActivitySnapshotController.mPendingLoadActivity.size());
117         assertEquals(openingWindow.mActivityRecord,
118                 mActivitySnapshotController.mPendingDeleteActivity.valueAt(0));
119         assertEquals(belowOpen.mActivityRecord,
120                 mActivitySnapshotController.mPendingLoadActivity.valueAt(0));
121     }
122 
123     @Test
testTaskTransition()124     public void testTaskTransition() {
125         final Task closeTask = createTask(mDisplayContent);
126         // note for createAppWindow: the new child is added at index 0
127         final WindowState closingWindow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
128                 "closingWindow");
129         closingWindow.mActivityRecord.commitVisibility(
130                 false /* visible */, true /* performLayout */);
131         final WindowState closingWindowBelow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
132                 "closingWindowBelow");
133         closingWindowBelow.mActivityRecord.commitVisibility(
134                 false /* visible */, true /* performLayout */);
135 
136         final Task openTask = createTask(mDisplayContent);
137         final WindowState openingWindow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
138                 "openingWindow");
139         openingWindow.mActivityRecord.commitVisibility(
140                 true /* visible */, true /* performLayout */);
141         final WindowState openingWindowBelow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
142                 "openingWindowBelow");
143         openingWindowBelow.mActivityRecord.commitVisibility(
144                 false /* visible */, true /* performLayout */);
145         final ArrayList<WindowContainer> windows = new ArrayList<>();
146         windows.add(closeTask);
147         windows.add(openTask);
148         mActivitySnapshotController.handleTransitionFinish(windows);
149 
150         assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
151         assertEquals(closingWindowBelow.mActivityRecord,
152                 mActivitySnapshotController.mPendingRemoveActivity.valueAt(0));
153         assertEquals(1, mActivitySnapshotController.mPendingLoadActivity.size());
154         assertEquals(openingWindowBelow.mActivityRecord,
155                 mActivitySnapshotController.mPendingLoadActivity.valueAt(0));
156     }
157 }
158