blob: b6f181758d3a087291424f8057866816425ed8fe [file] [log] [blame]
Bryce Leeaf691c02017-03-20 14:20:22 -07001/*
Wale Ogunwale59507092018-10-29 09:00:30 -07002 * Copyright (C) 2018 The Android Open Source Project
Bryce Leeaf691c02017-03-20 14:20:22 -07003 *
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
Wale Ogunwale59507092018-10-29 09:00:30 -070014 * limitations under the License
Bryce Leeaf691c02017-03-20 14:20:22 -070015 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Bryce Leeaf691c02017-03-20 14:20:22 -070018
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070019import static android.view.Display.DEFAULT_DISPLAY;
Bryce Lee0bd8d422018-01-09 09:45:57 -080020
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090021import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
22import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
23import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
24import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
25import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
26import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
Wale Ogunwale59507092018-10-29 09:00:30 -070027import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
28import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
29import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
30import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
Adrian Roose99bc052017-11-20 17:55:31 +010031
Bryce Lee04ab3462017-04-10 15:06:33 -070032import static org.junit.Assert.assertEquals;
Bryce Lee1533b2b2017-09-14 17:06:41 -070033import static org.junit.Assert.assertFalse;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080034import static org.junit.Assert.assertNotNull;
Bryce Lee04ab3462017-04-10 15:06:33 -070035import static org.junit.Assert.assertNull;
Bryce Lee1533b2b2017-09-14 17:06:41 -070036import static org.junit.Assert.assertTrue;
chaviw82a0ba82018-03-15 14:26:29 -070037
38import android.app.ActivityOptions;
Bryce Lee0bd8d422018-01-09 09:45:57 -080039import android.app.servertransaction.ClientTransaction;
40import android.app.servertransaction.PauseActivityItem;
Andrii Kulian3a1619d2017-07-07 14:38:09 -070041import android.graphics.Rect;
Bryce Leeaf691c02017-03-20 14:20:22 -070042import android.platform.test.annotations.Presubmit;
Andrii Kulian04470682018-01-10 15:32:31 -080043import android.util.MutableBoolean;
Bryce Leeaf691c02017-03-20 14:20:22 -070044
Brett Chabota26eda92018-07-23 13:08:30 -070045import androidx.test.filters.MediumTest;
Brett Chabota26eda92018-07-23 13:08:30 -070046
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070047import org.junit.Before;
Bryce Leeaf691c02017-03-20 14:20:22 -070048import org.junit.Test;
Andrii Kulian04470682018-01-10 15:32:31 -080049import org.mockito.invocation.InvocationOnMock;
Bryce Lee0bd8d422018-01-09 09:45:57 -080050
Bryce Leeaf691c02017-03-20 14:20:22 -070051/**
52 * Tests for the {@link ActivityRecord} class.
53 *
54 * Build/Install/Run:
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090055 * atest WmTests:ActivityRecordTests
Bryce Leeaf691c02017-03-20 14:20:22 -070056 */
57@MediumTest
Bryce Lee3115bdf2017-04-05 08:39:40 -070058@Presubmit
Bryce Leeaf691c02017-03-20 14:20:22 -070059public class ActivityRecordTests extends ActivityTestsBase {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070060 private TestActivityStack mStack;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070061 private TaskRecord mTask;
62 private ActivityRecord mActivity;
63
64 @Before
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070065 public void setUp() throws Exception {
Riddle Hsub70b36d2018-09-11 21:20:02 +080066 setupActivityTaskManagerService();
Wale Ogunwaled32da472018-11-16 07:19:28 -080067 mStack = new StackBuilder(mRootActivityContainer).build();
Louis Changf2835df2018-10-17 15:14:45 +080068 mTask = mStack.getChildAt(0);
69 mActivity = mTask.getTopActivity();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070070 }
71
Bryce Leeaf691c02017-03-20 14:20:22 -070072 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090073 public void testStackCleanupOnClearingTask() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070074 mActivity.setTask(null);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070075 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 1);
Bryce Leeaf691c02017-03-20 14:20:22 -070076 }
77
78 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090079 public void testStackCleanupOnActivityRemoval() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070080 mTask.removeActivity(mActivity);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070081 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 1);
Bryce Leeaf691c02017-03-20 14:20:22 -070082 }
83
84 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090085 public void testStackCleanupOnTaskRemoval() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070086 mStack.removeTask(mTask, null /*reason*/, REMOVE_TASK_MODE_MOVING);
Bryce Lee04ab3462017-04-10 15:06:33 -070087 // Stack should be gone on task removal.
Wale Ogunwaled32da472018-11-16 07:19:28 -080088 assertNull(mService.mRootActivityContainer.getStack(mStack.mStackId));
Bryce Leeaf691c02017-03-20 14:20:22 -070089 }
90
91 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090092 public void testNoCleanupMovingActivityInSameStack() {
Bryce Lee18d51592017-10-25 10:22:19 -070093 final TaskRecord newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack)
94 .build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070095 mActivity.reparent(newTask, 0, null /*reason*/);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070096 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 0);
Bryce Leeaf691c02017-03-20 14:20:22 -070097 }
Andrii Kulian3a1619d2017-07-07 14:38:09 -070098
Andreas Gampecea9e6d2018-02-22 18:06:44 -080099 @Test
Bryce Lee0bd8d422018-01-09 09:45:57 -0800100 public void testPausingWhenVisibleFromStopped() throws Exception {
Andrii Kulian04470682018-01-10 15:32:31 -0800101 final MutableBoolean pauseFound = new MutableBoolean(false);
102 doAnswer((InvocationOnMock invocationOnMock) -> {
103 final ClientTransaction transaction = invocationOnMock.getArgument(0);
104 if (transaction.getLifecycleStateRequest() instanceof PauseActivityItem) {
105 pauseFound.value = true;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800106 }
Andrii Kulian04470682018-01-10 15:32:31 -0800107 return null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700108 }).when(mActivity.app.getThread()).scheduleTransaction(any());
Bryce Leed939cf02018-03-12 09:04:44 -0700109
Bryce Lee7ace3952018-02-16 14:34:32 -0800110 mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
Bryce Lee0bd8d422018-01-09 09:45:57 -0800111
Bryce Leed939cf02018-03-12 09:04:44 -0700112 // The activity is in the focused stack so it should not move to paused.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700113 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Leed939cf02018-03-12 09:04:44 -0700114 assertTrue(mActivity.isState(STOPPED));
115 assertFalse(pauseFound.value);
Andrii Kulian04470682018-01-10 15:32:31 -0800116
Bryce Leed939cf02018-03-12 09:04:44 -0700117 // Clear focused stack
Wale Ogunwaled32da472018-11-16 07:19:28 -0800118 final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700119 when(display.getFocusedStack()).thenReturn(null);
Bryce Leed939cf02018-03-12 09:04:44 -0700120
121 // In the unfocused stack, the activity should move to paused.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700122 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Lee7ace3952018-02-16 14:34:32 -0800123 assertTrue(mActivity.isState(PAUSING));
Andrii Kulian04470682018-01-10 15:32:31 -0800124 assertTrue(pauseFound.value);
Bryce Lee052957b2018-01-16 11:13:30 -0800125
126 // Make sure that the state does not change for current non-stopping states.
Bryce Lee7ace3952018-02-16 14:34:32 -0800127 mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
Bryce Lee052957b2018-01-16 11:13:30 -0800128
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700129 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Lee052957b2018-01-16 11:13:30 -0800130
Bryce Lee7ace3952018-02-16 14:34:32 -0800131 assertTrue(mActivity.isState(INITIALIZING));
Bryce Leea0fb8e02018-02-28 14:21:07 -0800132
133 // Make sure the state does not change if we are not the current top activity.
134 mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind");
135
136 // Make sure that the state does not change when we have an activity becoming translucent
137 final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
138 mStack.mTranslucentActivityWaiting = topActivity;
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700139 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Leea0fb8e02018-02-28 14:21:07 -0800140
141 assertTrue(mActivity.isState(STOPPED));
Bryce Lee0bd8d422018-01-09 09:45:57 -0800142 }
143
144 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900145 public void testPositionLimitedAspectRatioNavBarBottom() {
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700146 verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f,
147 new Rect(0, 0, 1000, 1500));
148 }
149
150 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900151 public void testPositionLimitedAspectRatioNavBarLeft() {
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700152 verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f,
153 new Rect(500, 0, 2000, 1000));
154 }
155
156 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900157 public void testPositionLimitedAspectRatioNavBarRight() {
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700158 verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f,
159 new Rect(0, 0, 1500, 1000));
160 }
161
162 private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
163 float aspectRatio, Rect expectedActivityBounds) {
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700164 // Verify with nav bar on the right.
Tiger Huang7c610aa2018-10-27 00:01:01 +0800165 when(mService.mWindowManager.getNavBarPosition(mActivity.getDisplayId()))
166 .thenReturn(navBarPosition);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700167 mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
168 mActivity.info.maxAspectRatio = aspectRatio;
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800169 mActivity.ensureActivityConfiguration(
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700170 0 /* globalChanges */, false /* preserveWindow */);
171 assertEquals(expectedActivityBounds, mActivity.getBounds());
172 }
173
Bryce Lee1533b2b2017-09-14 17:06:41 -0700174 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900175 public void testCanBeLaunchedOnDisplay() {
Riddle Hsu16567132018-08-16 21:37:47 +0800176 mService.mSupportsMultiWindow = true;
177 final ActivityRecord activity = new ActivityBuilder(mService).build();
Bryce Lee1533b2b2017-09-14 17:06:41 -0700178
Riddle Hsu16567132018-08-16 21:37:47 +0800179 // An activity can be launched on default display.
180 assertTrue(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY));
181 // An activity cannot be launched on a non-existent display.
182 assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1));
Bryce Lee1533b2b2017-09-14 17:06:41 -0700183 }
184
chaviw82a0ba82018-03-15 14:26:29 -0700185 @Test
186 public void testsApplyOptionsLocked() {
187 ActivityOptions activityOptions = ActivityOptions.makeBasic();
188
189 // Set and apply options for ActivityRecord. Pending options should be cleared
190 mActivity.updateOptionsLocked(activityOptions);
191 mActivity.applyOptionsLocked();
192 assertNull(mActivity.pendingOptions);
193
194 // Set options for two ActivityRecords in same Task. Apply one ActivityRecord options.
195 // Pending options should be cleared for both ActivityRecords
196 ActivityRecord activity2 = new ActivityBuilder(mService).setTask(mTask).build();
197 activity2.updateOptionsLocked(activityOptions);
198 mActivity.updateOptionsLocked(activityOptions);
199 mActivity.applyOptionsLocked();
200 assertNull(mActivity.pendingOptions);
201 assertNull(activity2.pendingOptions);
202
203 // Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
204 // Pending options should be cleared for only ActivityRecord that was applied
205 TaskRecord task2 = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
206 activity2 = new ActivityBuilder(mService).setTask(task2).build();
207 activity2.updateOptionsLocked(activityOptions);
208 mActivity.updateOptionsLocked(activityOptions);
209 mActivity.applyOptionsLocked();
210 assertNull(mActivity.pendingOptions);
211 assertNotNull(activity2.pendingOptions);
212 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700213}