Loading services/core/java/com/android/server/am/ActivityStack.java +5 −2 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ import android.util.Slog; import android.util.SparseArray; import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.BatteryStatsImpl; import com.android.server.Watchdog; Loading Loading @@ -230,9 +231,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // activities and there is a specific combination of stacks. private static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2; @VisibleForTesting /* The various modes for the method {@link #removeTask}. */ // Task is being completely removed from all stacks in the system. private static final int REMOVE_TASK_MODE_DESTROYING = 0; protected static final int REMOVE_TASK_MODE_DESTROYING = 0; // Task is being removed from this stack so we can add it to another stack. In the case we are // moving we don't want to perform some operations on the task like removing it from window // manager or recents. Loading Loading @@ -3990,7 +3992,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // where we are destroying the task, move this back into removeTask() mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY); task.removeWindowContainer(); } removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } Loading Loading @@ -5082,6 +5083,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mRecentTasks.remove(task); task.removedFromRecents(); } task.removeWindowContainer(); } if (mTaskHistory.isEmpty()) { Loading services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.am; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import android.content.ComponentName; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.runner.RunWith; import org.junit.Test; /** * Tests for the {@link ActivityStack} class. * * Build/Install/Run: * bit FrameworksServicesTests:com.android.server.am.ActivityStackTests */ @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStackTests extends ActivityTestsBase { private final ComponentName testActivityComponent = ComponentName.unflattenFromString("com.foo/.BarActivity"); @Test public void testEmptyTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TestActivityStack testStack = new ActivityStackBuilder(service).build(); final TaskRecord task = createTask(service, testActivityComponent, testStack); assertNotNull(task.getWindowContainerController()); testStack.removeTask(task, "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNull(task.getWindowContainerController()); } @Test public void testOccupiedTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TestActivityStack testStack = new ActivityStackBuilder(service).build(); final TaskRecord task = createTask(service, testActivityComponent, testStack); final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); assertNotNull(task.getWindowContainerController()); testStack.removeTask(task, "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNotNull(task.getWindowContainerController()); } } services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +24 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static org.mockito.Mockito.mock; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -62,14 +63,16 @@ public class ActivityTestsBase { } protected ActivityManagerService createActivityManagerService() { return new TestActivityManagerService(mContext); final ActivityManagerService service = new TestActivityManagerService(mContext); service.mWindowManager = WindowTestUtils.getWindowManagerService(mContext); return service; } protected static TestActivityStack createActivityStack(ActivityManagerService service, int stackId, int displayId, boolean onTop) { if (service.mStackSupervisor instanceof TestActivityStackSupervisor) { final TestActivityStack stack = ((TestActivityStackSupervisor) service.mStackSupervisor) .createTestStack(stackId, onTop); .createTestStack(service, stackId, onTop); return stack; } Loading Loading @@ -109,7 +112,7 @@ public class ActivityTestsBase { intent.setComponent(component); final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/, null /*_taskDescription*/, null /*thumbnailInfo*/); null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo()); stack.addTask(task, true, "creating test task"); task.setStack(stack); task.createWindowContainer(true, true); Loading Loading @@ -146,25 +149,39 @@ public class ActivityTestsBase { void updateUIDsPresentOnDisplay() { } public TestActivityStack createTestStack(int stackId, boolean onTop) { public TestActivityStack createTestStack(ActivityManagerService service, int stackId, boolean onTop) { final ActivityDisplay display = new ActivityDisplay(); final TestActivityContainer container = new TestActivityContainer(stackId, display, onTop); new TestActivityContainer(service, stackId, display, onTop); return container.getStack(); } private class TestActivityContainer extends ActivityContainer { private ActivityManagerService mService; private TestActivityStack mStack; TestActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) { private boolean mOnTop; TestActivityContainer(ActivityManagerService service, int stackId, ActivityDisplay activityDisplay, boolean onTop) { super(stackId, activityDisplay, onTop); mService = service; } @Override protected void createStack(int stackId, boolean onTop) { mStack = new TestActivityStack(this, null /*recentTasks*/, onTop); // normally stack creation is done here. However we need to do it on demand since // we cannot set {@link mService} by the time the super constructor calling this // method is invoked. mOnTop = onTop; } public TestActivityStack getStack() { if (mStack == null) { mStack = new TestActivityStack(this, new RecentTasks(mService, mService.mStackSupervisor), mOnTop); } return mStack; } } Loading Loading
services/core/java/com/android/server/am/ActivityStack.java +5 −2 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ import android.util.Slog; import android.util.SparseArray; import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.BatteryStatsImpl; import com.android.server.Watchdog; Loading Loading @@ -230,9 +231,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // activities and there is a specific combination of stacks. private static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2; @VisibleForTesting /* The various modes for the method {@link #removeTask}. */ // Task is being completely removed from all stacks in the system. private static final int REMOVE_TASK_MODE_DESTROYING = 0; protected static final int REMOVE_TASK_MODE_DESTROYING = 0; // Task is being removed from this stack so we can add it to another stack. In the case we are // moving we don't want to perform some operations on the task like removing it from window // manager or recents. Loading Loading @@ -3990,7 +3992,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // where we are destroying the task, move this back into removeTask() mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY); task.removeWindowContainer(); } removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } Loading Loading @@ -5082,6 +5083,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mRecentTasks.remove(task); task.removedFromRecents(); } task.removeWindowContainer(); } if (mTaskHistory.isEmpty()) { Loading
services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.am; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import android.content.ComponentName; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.runner.RunWith; import org.junit.Test; /** * Tests for the {@link ActivityStack} class. * * Build/Install/Run: * bit FrameworksServicesTests:com.android.server.am.ActivityStackTests */ @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStackTests extends ActivityTestsBase { private final ComponentName testActivityComponent = ComponentName.unflattenFromString("com.foo/.BarActivity"); @Test public void testEmptyTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TestActivityStack testStack = new ActivityStackBuilder(service).build(); final TaskRecord task = createTask(service, testActivityComponent, testStack); assertNotNull(task.getWindowContainerController()); testStack.removeTask(task, "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNull(task.getWindowContainerController()); } @Test public void testOccupiedTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TestActivityStack testStack = new ActivityStackBuilder(service).build(); final TaskRecord task = createTask(service, testActivityComponent, testStack); final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); assertNotNull(task.getWindowContainerController()); testStack.removeTask(task, "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNotNull(task.getWindowContainerController()); } }
services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +24 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static org.mockito.Mockito.mock; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -62,14 +63,16 @@ public class ActivityTestsBase { } protected ActivityManagerService createActivityManagerService() { return new TestActivityManagerService(mContext); final ActivityManagerService service = new TestActivityManagerService(mContext); service.mWindowManager = WindowTestUtils.getWindowManagerService(mContext); return service; } protected static TestActivityStack createActivityStack(ActivityManagerService service, int stackId, int displayId, boolean onTop) { if (service.mStackSupervisor instanceof TestActivityStackSupervisor) { final TestActivityStack stack = ((TestActivityStackSupervisor) service.mStackSupervisor) .createTestStack(stackId, onTop); .createTestStack(service, stackId, onTop); return stack; } Loading Loading @@ -109,7 +112,7 @@ public class ActivityTestsBase { intent.setComponent(component); final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/, null /*_taskDescription*/, null /*thumbnailInfo*/); null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo()); stack.addTask(task, true, "creating test task"); task.setStack(stack); task.createWindowContainer(true, true); Loading Loading @@ -146,25 +149,39 @@ public class ActivityTestsBase { void updateUIDsPresentOnDisplay() { } public TestActivityStack createTestStack(int stackId, boolean onTop) { public TestActivityStack createTestStack(ActivityManagerService service, int stackId, boolean onTop) { final ActivityDisplay display = new ActivityDisplay(); final TestActivityContainer container = new TestActivityContainer(stackId, display, onTop); new TestActivityContainer(service, stackId, display, onTop); return container.getStack(); } private class TestActivityContainer extends ActivityContainer { private ActivityManagerService mService; private TestActivityStack mStack; TestActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) { private boolean mOnTop; TestActivityContainer(ActivityManagerService service, int stackId, ActivityDisplay activityDisplay, boolean onTop) { super(stackId, activityDisplay, onTop); mService = service; } @Override protected void createStack(int stackId, boolean onTop) { mStack = new TestActivityStack(this, null /*recentTasks*/, onTop); // normally stack creation is done here. However we need to do it on demand since // we cannot set {@link mService} by the time the super constructor calling this // method is invoked. mOnTop = onTop; } public TestActivityStack getStack() { if (mStack == null) { mStack = new TestActivityStack(this, new RecentTasks(mService, mService.mStackSupervisor), mOnTop); } return mStack; } } Loading