blob: 9af2b96f3f78eba64dd30010f0fc72d1aed64d21 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.Task.ActivityState.FINISHING;
import static com.android.server.wm.Task.ActivityState.PAUSED;
import static com.android.server.wm.Task.ActivityState.PAUSING;
import static com.android.server.wm.Task.ActivityState.STOPPED;
import static com.android.server.wm.Task.ActivityState.STOPPING;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests for RootWindowContainer.
*
* Build/Install/Run:
* atest WmTests:RootWindowContainerTests
*/
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testUpdateDefaultDisplayWindowingModeOnSettingsRetrieved() {
assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
mWm.getDefaultDisplayContentLocked().getWindowingMode());
mWm.mIsPc = true;
mWm.mAtmService.mSupportsFreeformWindowManagement = true;
mWm.mRoot.onSettingsRetrieved();
assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
mWm.getDefaultDisplayContentLocked().getWindowingMode());
}
/**
* This test ensures that an existing single instance activity with alias name can be found by
* the same activity info. So {@link ActivityStarter#getReusableTask} won't miss it that leads
* to create an unexpected new instance.
*/
@Test
public void testFindActivityByTargetComponent() {
final ComponentName aliasComponent = ComponentName.createRelative(
DEFAULT_COMPONENT_PACKAGE_NAME, ".AliasActivity");
final ComponentName targetComponent = ComponentName.createRelative(
aliasComponent.getPackageName(), ".TargetActivity");
final ActivityRecord activity = new ActivityBuilder(mWm.mAtmService)
.setComponent(aliasComponent)
.setTargetActivity(targetComponent.getClassName())
.setLaunchMode(ActivityInfo.LAUNCH_SINGLE_INSTANCE)
.setCreateTask(true)
.build();
assertEquals(activity, mWm.mRoot.findActivity(activity.intent, activity.info,
false /* compareIntentFilters */));
}
@Test
public void testAllPausedActivitiesComplete() {
DisplayContent displayContent = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
TaskDisplayArea taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.getRootTaskAt(0);
ActivityRecord activity = createActivityRecord(displayContent);
stack.mPausingActivity = activity;
activity.setState(PAUSING, "test PAUSING");
assertThat(mWm.mRoot.allPausedActivitiesComplete()).isFalse();
activity.setState(PAUSED, "test PAUSED");
assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue();
activity.setState(STOPPED, "test STOPPED");
assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue();
activity.setState(STOPPING, "test STOPPING");
assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue();
activity.setState(FINISHING, "test FINISHING");
assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue();
}
@Test
public void testTaskLayerRank() {
final Task rootTask = new TaskBuilder(mSupervisor).build();
final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
new ActivityBuilder(mAtm).setTask(task1).build().mVisibleRequested = true;
// RootWindowContainer#invalidateTaskLayers should post to update.
waitHandlerIdle(mWm.mH);
assertEquals(1, task1.mLayerRank);
// Only tasks that directly contain activities have a ranking.
assertEquals(Task.LAYER_RANK_INVISIBLE, rootTask.mLayerRank);
final Task task2 = new TaskBuilder(mSupervisor).build();
new ActivityBuilder(mAtm).setTask(task2).build().mVisibleRequested = true;
waitHandlerIdle(mWm.mH);
// Note that ensureActivitiesVisible is disabled in SystemServicesTestRule, so both the
// activities have the visible rank.
assertEquals(2, task1.mLayerRank);
// The task2 is the top task, so it has a lower rank as a higher priority oom score.
assertEquals(1, task2.mLayerRank);
task2.moveToBack("test", null /* task */);
waitHandlerIdle(mWm.mH);
assertEquals(1, task1.mLayerRank);
assertEquals(2, task2.mLayerRank);
}
@Test
public void testForceStopPackage() {
final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = task.getTopMostActivity();
final WindowProcessController wpc = activity.app;
final ActivityRecord[] activities = {
activity,
new ActivityBuilder(mWm.mAtmService).setTask(task).setUseProcess(wpc).build(),
new ActivityBuilder(mWm.mAtmService).setTask(task).setUseProcess(wpc).build()
};
activities[0].detachFromProcess();
activities[1].finishing = true;
activities[1].destroyImmediately("test");
spyOn(wpc);
doReturn(true).when(wpc).isRemoved();
mWm.mAtmService.mInternal.onForceStopPackage(wpc.mInfo.packageName, true /* doit */,
false /* evenPersistent */, wpc.mUserId);
// The activity without process should be removed.
assertEquals(2, task.getChildCount());
wpc.handleAppDied();
// The activities with process should be removed because WindowProcessController#isRemoved.
assertFalse(task.hasChild());
assertFalse(wpc.hasActivities());
}
}