blob: 457d9c0f2deeac9c6d82b9008d3d9691a5da79b3 [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;
Garfield Tan36a69ad2019-01-16 17:08:23 -080022import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090023import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
Riddle Hsu7b766fd2019-01-28 21:14:59 +080024import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Garfield Tan0443b372019-01-04 15:00:13 -080025import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Garfield Tan36a69ad2019-01-16 17:08:23 -080026import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
Garfield Tan0443b372019-01-04 15:00:13 -080027import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
Andrii Kulian0c869cc2019-02-06 19:50:32 -080028import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Garfield Tan0443b372019-01-04 15:00:13 -080029import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090030import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
Wale Ogunwale59507092018-10-29 09:00:30 -070031import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
32import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
Andrii Kulian6b321512019-01-23 06:37:00 +000033import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
Wale Ogunwale59507092018-10-29 09:00:30 -070034import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
35import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
Andrii Kulian0c869cc2019-02-06 19:50:32 -080036import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
37import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
38import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
Adrian Roose99bc052017-11-20 17:55:31 +010039
Bryce Lee04ab3462017-04-10 15:06:33 -070040import static org.junit.Assert.assertEquals;
Bryce Lee1533b2b2017-09-14 17:06:41 -070041import static org.junit.Assert.assertFalse;
Riddle Hsu7b766fd2019-01-28 21:14:59 +080042import static org.junit.Assert.assertNotEquals;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080043import static org.junit.Assert.assertNotNull;
Bryce Lee04ab3462017-04-10 15:06:33 -070044import static org.junit.Assert.assertNull;
Bryce Lee1533b2b2017-09-14 17:06:41 -070045import static org.junit.Assert.assertTrue;
chaviw82a0ba82018-03-15 14:26:29 -070046
47import android.app.ActivityOptions;
Garfield Tan36a69ad2019-01-16 17:08:23 -080048import android.app.servertransaction.ActivityConfigurationChangeItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -080049import android.app.servertransaction.ClientTransaction;
50import android.app.servertransaction.PauseActivityItem;
Garfield Tanf6cc5c92019-01-15 13:54:12 -080051import android.content.pm.ActivityInfo;
Garfield Tan0443b372019-01-04 15:00:13 -080052import android.content.res.Configuration;
Andrii Kulian3a1619d2017-07-07 14:38:09 -070053import android.graphics.Rect;
Bryce Leeaf691c02017-03-20 14:20:22 -070054import android.platform.test.annotations.Presubmit;
Garfield Tanf6cc5c92019-01-15 13:54:12 -080055import android.util.MergedConfiguration;
Andrii Kulian04470682018-01-10 15:32:31 -080056import android.util.MutableBoolean;
Bryce Leeaf691c02017-03-20 14:20:22 -070057
Brett Chabota26eda92018-07-23 13:08:30 -070058import androidx.test.filters.MediumTest;
Brett Chabota26eda92018-07-23 13:08:30 -070059
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070060import org.junit.Before;
Bryce Leeaf691c02017-03-20 14:20:22 -070061import org.junit.Test;
Andrii Kulian04470682018-01-10 15:32:31 -080062import org.mockito.invocation.InvocationOnMock;
Bryce Lee0bd8d422018-01-09 09:45:57 -080063
Bryce Leeaf691c02017-03-20 14:20:22 -070064/**
65 * Tests for the {@link ActivityRecord} class.
66 *
67 * Build/Install/Run:
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090068 * atest WmTests:ActivityRecordTests
Bryce Leeaf691c02017-03-20 14:20:22 -070069 */
70@MediumTest
Bryce Lee3115bdf2017-04-05 08:39:40 -070071@Presubmit
Bryce Leeaf691c02017-03-20 14:20:22 -070072public class ActivityRecordTests extends ActivityTestsBase {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070073 private TestActivityStack mStack;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070074 private TaskRecord mTask;
75 private ActivityRecord mActivity;
76
77 @Before
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070078 public void setUp() throws Exception {
Yunfan Chen279f5582018-12-12 15:24:50 -080079 mStack = (TestActivityStack) new StackBuilder(mRootActivityContainer).build();
Louis Changf2835df2018-10-17 15:14:45 +080080 mTask = mStack.getChildAt(0);
81 mActivity = mTask.getTopActivity();
Andrii Kulian6b321512019-01-23 06:37:00 +000082
83 doReturn(false).when(mService).isBooting();
84 doReturn(true).when(mService).isBooted();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070085 }
86
Bryce Leeaf691c02017-03-20 14:20:22 -070087 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090088 public void testStackCleanupOnClearingTask() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070089 mActivity.setTask(null);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070090 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 1);
Bryce Leeaf691c02017-03-20 14:20:22 -070091 }
92
93 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090094 public void testStackCleanupOnActivityRemoval() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070095 mTask.removeActivity(mActivity);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070096 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 1);
Bryce Leeaf691c02017-03-20 14:20:22 -070097 }
98
99 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900100 public void testStackCleanupOnTaskRemoval() {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700101 mStack.removeTask(mTask, null /*reason*/, REMOVE_TASK_MODE_MOVING);
Bryce Lee04ab3462017-04-10 15:06:33 -0700102 // Stack should be gone on task removal.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800103 assertNull(mService.mRootActivityContainer.getStack(mStack.mStackId));
Bryce Leeaf691c02017-03-20 14:20:22 -0700104 }
105
106 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900107 public void testNoCleanupMovingActivityInSameStack() {
Bryce Lee18d51592017-10-25 10:22:19 -0700108 final TaskRecord newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack)
109 .build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700110 mActivity.reparent(newTask, 0, null /*reason*/);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700111 assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 0);
Bryce Leeaf691c02017-03-20 14:20:22 -0700112 }
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700113
Andreas Gampecea9e6d2018-02-22 18:06:44 -0800114 @Test
Bryce Lee0bd8d422018-01-09 09:45:57 -0800115 public void testPausingWhenVisibleFromStopped() throws Exception {
Andrii Kulian04470682018-01-10 15:32:31 -0800116 final MutableBoolean pauseFound = new MutableBoolean(false);
117 doAnswer((InvocationOnMock invocationOnMock) -> {
118 final ClientTransaction transaction = invocationOnMock.getArgument(0);
119 if (transaction.getLifecycleStateRequest() instanceof PauseActivityItem) {
120 pauseFound.value = true;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800121 }
Andrii Kulian04470682018-01-10 15:32:31 -0800122 return null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700123 }).when(mActivity.app.getThread()).scheduleTransaction(any());
Bryce Leed939cf02018-03-12 09:04:44 -0700124
Bryce Lee7ace3952018-02-16 14:34:32 -0800125 mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
Bryce Lee0bd8d422018-01-09 09:45:57 -0800126
Andrii Kulian6b321512019-01-23 06:37:00 +0000127 // The activity is in the focused stack so it should be resumed.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700128 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Andrii Kulian6b321512019-01-23 06:37:00 +0000129 assertTrue(mActivity.isState(RESUMED));
Bryce Leed939cf02018-03-12 09:04:44 -0700130 assertFalse(pauseFound.value);
Andrii Kulian04470682018-01-10 15:32:31 -0800131
Andrii Kulian6b321512019-01-23 06:37:00 +0000132 // Make the activity non focusable
133 mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
134 doReturn(false).when(mActivity).isFocusable();
Bryce Leed939cf02018-03-12 09:04:44 -0700135
Andrii Kulian6b321512019-01-23 06:37:00 +0000136 // If the activity is not focusable, it should move to paused.
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700137 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Lee7ace3952018-02-16 14:34:32 -0800138 assertTrue(mActivity.isState(PAUSING));
Andrii Kulian04470682018-01-10 15:32:31 -0800139 assertTrue(pauseFound.value);
Bryce Lee052957b2018-01-16 11:13:30 -0800140
141 // Make sure that the state does not change for current non-stopping states.
Bryce Lee7ace3952018-02-16 14:34:32 -0800142 mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
Andrii Kulian6b321512019-01-23 06:37:00 +0000143 doReturn(true).when(mActivity).isFocusable();
Bryce Lee052957b2018-01-16 11:13:30 -0800144
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700145 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Lee052957b2018-01-16 11:13:30 -0800146
Bryce Lee7ace3952018-02-16 14:34:32 -0800147 assertTrue(mActivity.isState(INITIALIZING));
Bryce Leea0fb8e02018-02-28 14:21:07 -0800148
149 // Make sure the state does not change if we are not the current top activity.
150 mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind");
151
152 // Make sure that the state does not change when we have an activity becoming translucent
153 final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
154 mStack.mTranslucentActivityWaiting = topActivity;
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700155 mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
Bryce Leea0fb8e02018-02-28 14:21:07 -0800156
157 assertTrue(mActivity.isState(STOPPED));
Bryce Lee0bd8d422018-01-09 09:45:57 -0800158 }
159
Riddle Hsu0a343c32018-12-21 00:40:48 +0800160 private void ensureActivityConfiguration() {
161 mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
162 }
163
Bryce Lee1533b2b2017-09-14 17:06:41 -0700164 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900165 public void testCanBeLaunchedOnDisplay() {
Riddle Hsu16567132018-08-16 21:37:47 +0800166 mService.mSupportsMultiWindow = true;
167 final ActivityRecord activity = new ActivityBuilder(mService).build();
Bryce Lee1533b2b2017-09-14 17:06:41 -0700168
Riddle Hsu16567132018-08-16 21:37:47 +0800169 // An activity can be launched on default display.
170 assertTrue(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY));
171 // An activity cannot be launched on a non-existent display.
172 assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1));
Bryce Lee1533b2b2017-09-14 17:06:41 -0700173 }
174
chaviw82a0ba82018-03-15 14:26:29 -0700175 @Test
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800176 public void testRestartProcessIfVisible() {
177 doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
178 mActivity.getParent().getWindowConfiguration().setAppBounds(0, 0, 500, 1000);
179 mActivity.visible = true;
180 mActivity.haveState = false;
181 mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
182 mActivity.info.maxAspectRatio = 1.5f;
183 mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
184 final Rect originalOverrideBounds = new Rect(0, 0, 400, 600);
185 mActivity.setBounds(originalOverrideBounds);
186
187 mService.restartActivityProcessIfVisible(mActivity.appToken);
188
189 assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState());
190 assertNotEquals(originalOverrideBounds, mActivity.getBounds());
191 }
192
193 @Test
chaviw82a0ba82018-03-15 14:26:29 -0700194 public void testsApplyOptionsLocked() {
195 ActivityOptions activityOptions = ActivityOptions.makeBasic();
196
197 // Set and apply options for ActivityRecord. Pending options should be cleared
198 mActivity.updateOptionsLocked(activityOptions);
199 mActivity.applyOptionsLocked();
200 assertNull(mActivity.pendingOptions);
201
202 // Set options for two ActivityRecords in same Task. Apply one ActivityRecord options.
203 // Pending options should be cleared for both ActivityRecords
204 ActivityRecord activity2 = new ActivityBuilder(mService).setTask(mTask).build();
205 activity2.updateOptionsLocked(activityOptions);
206 mActivity.updateOptionsLocked(activityOptions);
207 mActivity.applyOptionsLocked();
208 assertNull(mActivity.pendingOptions);
209 assertNull(activity2.pendingOptions);
210
211 // Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
212 // Pending options should be cleared for only ActivityRecord that was applied
213 TaskRecord task2 = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
214 activity2 = new ActivityBuilder(mService).setTask(task2).build();
215 activity2.updateOptionsLocked(activityOptions);
216 mActivity.updateOptionsLocked(activityOptions);
217 mActivity.applyOptionsLocked();
218 assertNull(mActivity.pendingOptions);
219 assertNotNull(activity2.pendingOptions);
220 }
Garfield Tan0443b372019-01-04 15:00:13 -0800221
222 @Test
223 public void testNewOverrideConfigurationIncrementsSeq() {
224 final Configuration newConfig = new Configuration();
225
226 final int prevSeq = mActivity.getMergedOverrideConfiguration().seq;
227 mActivity.onRequestedOverrideConfigurationChanged(newConfig);
228 assertEquals(prevSeq + 1, mActivity.getMergedOverrideConfiguration().seq);
229 }
230
231 @Test
232 public void testNewParentConfigurationIncrementsSeq() {
233 final Configuration newConfig = new Configuration(
234 mTask.getRequestedOverrideConfiguration());
235 newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
236 ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
237
238 final int prevSeq = mActivity.getMergedOverrideConfiguration().seq;
239 mTask.onRequestedOverrideConfigurationChanged(newConfig);
240 assertEquals(prevSeq + 1, mActivity.getMergedOverrideConfiguration().seq);
241 }
242
243 @Test
244 public void testNotifiesSeqIncrementToAppToken() {
245 final Configuration appWindowTokenRequestedOrientation = mock(Configuration.class);
246 mActivity.mAppWindowToken = mock(AppWindowToken.class);
247 doReturn(appWindowTokenRequestedOrientation).when(mActivity.mAppWindowToken)
248 .getRequestedOverrideConfiguration();
249
250 final Configuration newConfig = new Configuration();
251 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
252
253 final int prevSeq = mActivity.getMergedOverrideConfiguration().seq;
254 mActivity.onRequestedOverrideConfigurationChanged(newConfig);
255 assertEquals(prevSeq + 1, appWindowTokenRequestedOrientation.seq);
256 verify(mActivity.mAppWindowToken).onMergedOverrideConfigurationChanged();
257 }
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800258
259 @Test
260 public void testSetsRelaunchReason_NotDragResizing() {
261 mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing");
262
263 mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
264 mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
265 mActivity.getConfiguration()));
266
267 mActivity.info.configChanges &= ~ActivityInfo.CONFIG_ORIENTATION;
268 final Configuration newConfig = new Configuration(mTask.getConfiguration());
269 newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
270 ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
271 mTask.onRequestedOverrideConfigurationChanged(newConfig);
272
273 mActivity.mRelaunchReason = ActivityTaskManagerService.RELAUNCH_REASON_NONE;
274
Riddle Hsu0a343c32018-12-21 00:40:48 +0800275 ensureActivityConfiguration();
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800276
277 assertEquals(ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE,
278 mActivity.mRelaunchReason);
279 }
280
281 @Test
282 public void testSetsRelaunchReason_DragResizing() {
283 mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing");
284
285 mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
286 mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
287 mActivity.getConfiguration()));
288
289 mActivity.info.configChanges &= ~ActivityInfo.CONFIG_ORIENTATION;
290 final Configuration newConfig = new Configuration(mTask.getConfiguration());
291 newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
292 ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
293 mTask.onRequestedOverrideConfigurationChanged(newConfig);
294
295 doReturn(true).when(mTask.getTask()).isDragResizing();
296
297 mActivity.mRelaunchReason = ActivityTaskManagerService.RELAUNCH_REASON_NONE;
298
Riddle Hsu0a343c32018-12-21 00:40:48 +0800299 ensureActivityConfiguration();
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800300
301 assertEquals(ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE,
302 mActivity.mRelaunchReason);
303 }
304
305 @Test
306 public void testSetsRelaunchReason_NonResizeConfigChanges() {
307 mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing");
308
309 mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
310 mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
311 mActivity.getConfiguration()));
312
313 mActivity.info.configChanges &= ~ActivityInfo.CONFIG_FONT_SCALE;
314 final Configuration newConfig = new Configuration(mTask.getConfiguration());
315 newConfig.fontScale = 5;
316 mTask.onRequestedOverrideConfigurationChanged(newConfig);
317
318 mActivity.mRelaunchReason =
319 ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
320
Riddle Hsu0a343c32018-12-21 00:40:48 +0800321 ensureActivityConfiguration();
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800322
323 assertEquals(ActivityTaskManagerService.RELAUNCH_REASON_NONE,
324 mActivity.mRelaunchReason);
325 }
Garfield Tan36a69ad2019-01-16 17:08:23 -0800326
327 @Test
328 public void testSetRequestedOrientationUpdatesConfiguration() throws Exception {
329 mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing");
330
331 mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
332 mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
333 mActivity.getConfiguration()));
334
335 mActivity.info.configChanges |= ActivityInfo.CONFIG_ORIENTATION;
336 final Configuration newConfig = new Configuration(mActivity.getConfiguration());
337 newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
338 ? Configuration.ORIENTATION_LANDSCAPE
339 : Configuration.ORIENTATION_PORTRAIT;
340
341 // Mimic the behavior that display doesn't handle app's requested orientation.
342 doAnswer(invocation -> {
343 mTask.onConfigurationChanged(newConfig);
344 return null;
345 }).when(mActivity.mAppWindowToken).setOrientation(anyInt(), any(), any());
346
347 final int requestedOrientation;
348 switch (newConfig.orientation) {
349 case Configuration.ORIENTATION_LANDSCAPE:
350 requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
351 break;
352 case Configuration.ORIENTATION_PORTRAIT:
353 requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
354 break;
355 default:
356 throw new IllegalStateException("Orientation in new config should be either"
357 + "landscape or portrait.");
358 }
359 mActivity.setRequestedOrientation(requestedOrientation);
360
361 final ActivityConfigurationChangeItem expected =
362 ActivityConfigurationChangeItem.obtain(newConfig);
363 verify(mService.getLifecycleManager()).scheduleTransaction(eq(mActivity.app.getThread()),
364 eq(mActivity.appToken), eq(expected));
365 }
Andrii Kulianf2195362019-01-31 18:20:11 -0800366
367 @Test
368 public void testShouldMakeActive_deferredResume() {
369 mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
370
371 mSupervisor.beginDeferResume();
372 assertEquals(false, mActivity.shouldMakeActive(null /* activeActivity */));
373
374 mSupervisor.endDeferResume();
375 assertEquals(true, mActivity.shouldMakeActive(null /* activeActivity */));
376 }
Garfield Tan40263302019-02-01 15:27:35 -0800377
378 @Test
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800379 public void testShouldResume_stackVisibility() {
380 mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
381 spyOn(mStack);
382
383 doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
384 assertEquals(true, mActivity.shouldResumeActivity(null /* activeActivity */));
385
386 doReturn(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT).when(mStack).getVisibility(null);
387 assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
388
389 doReturn(STACK_VISIBILITY_INVISIBLE).when(mStack).getVisibility(null);
390 assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
391 }
392
393 @Test
Garfield Tan40263302019-02-01 15:27:35 -0800394 public void testPushConfigurationWhenLaunchTaskBehind() throws Exception {
395 mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
396
397 final TestActivityStack stack = (TestActivityStack) new StackBuilder(mRootActivityContainer)
398 .build();
399 try {
400 stack.setIsTranslucent(false);
401 assertFalse(mStack.shouldBeVisible(null /* starting */));
402
403 mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
404 mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
405 mActivity.getConfiguration()));
406
407 mActivity.mLaunchTaskBehind = true;
408 mActivity.info.configChanges |= ActivityInfo.CONFIG_ORIENTATION;
409 final Configuration newConfig = new Configuration(mActivity.getConfiguration());
410 newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
411 ? Configuration.ORIENTATION_LANDSCAPE
412 : Configuration.ORIENTATION_PORTRAIT;
413
414 mTask.onConfigurationChanged(newConfig);
415
416 mActivity.ensureActivityConfiguration(0 /* globalChanges */,
417 false /* preserveWindow */, true /* ignoreStopState */);
418
419 final ActivityConfigurationChangeItem expected =
420 ActivityConfigurationChangeItem.obtain(newConfig);
421 verify(mService.getLifecycleManager()).scheduleTransaction(
422 eq(mActivity.app.getThread()), eq(mActivity.appToken), eq(expected));
423 } finally {
424 stack.getDisplay().removeChild(stack);
425 }
426 }
Riddle Hsu0a343c32018-12-21 00:40:48 +0800427
428 @Test
Riddle Hsu2560c3b2019-02-23 23:45:58 +0800429 public void testSizeCompatMode_FixedScreenConfigurationWhenMovingToDisplay() {
Riddle Hsu0a343c32018-12-21 00:40:48 +0800430 // Initialize different bounds on a new display.
431 final ActivityDisplay newDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
432 newDisplay.setBounds(0, 0, 1000, 2000);
433 newDisplay.getConfiguration().densityDpi = 300;
434
435 mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds());
436 mTask.getConfiguration().densityDpi = 200;
437 when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn(
438 ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
439 mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
440 mActivity.info.maxAspectRatio = 1.5f;
441 ensureActivityConfiguration();
442 final Rect originalBounds = new Rect(mActivity.getBounds());
443 final int originalDpi = mActivity.getConfiguration().densityDpi;
444
445 // Move the non-resizable activity to the new display.
446 mStack.reparent(newDisplay, true /* onTop */, false /* displayRemoved */);
447 ensureActivityConfiguration();
448
449 assertEquals(originalBounds, mActivity.getBounds());
450 assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
451 }
452
453 @Test
Riddle Hsu2560c3b2019-02-23 23:45:58 +0800454 public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() {
Riddle Hsu0a343c32018-12-21 00:40:48 +0800455 when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn(
456 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
457 mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds());
458 mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
459 mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
460 ensureActivityConfiguration();
461 final Rect originalBounds = new Rect(mActivity.getBounds());
462
463 // Change the size of current display.
464 mStack.getDisplay().setBounds(0, 0, 1000, 2000);
465 ensureActivityConfiguration();
466
467 assertEquals(originalBounds, mActivity.getBounds());
468 }
Riddle Hsu2560c3b2019-02-23 23:45:58 +0800469
470 @Test
471 public void testSizeCompatMode_FixedScreenLayoutSizeBits() {
472 final int fixedScreenLayout = Configuration.SCREENLAYOUT_LONG_NO
473 | Configuration.SCREENLAYOUT_SIZE_NORMAL;
474 mTask.getConfiguration().screenLayout = fixedScreenLayout
475 | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
476 mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds());
477 mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
478 mActivity.info.maxAspectRatio = 1.5f;
479 ensureActivityConfiguration();
480
481 // The initial configuration should inherit from parent.
482 assertEquals(mTask.getConfiguration().screenLayout,
483 mActivity.getConfiguration().screenLayout);
484
485 mTask.getConfiguration().screenLayout = Configuration.SCREENLAYOUT_LAYOUTDIR_RTL
486 | Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_LARGE;
487 mActivity.onConfigurationChanged(mTask.getConfiguration());
488
489 // The size and aspect ratio bits don't change, but the layout direction should be updated.
490 assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL,
491 mActivity.getConfiguration().screenLayout);
492 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700493}