Loading services/core/java/com/android/server/wm/LaunchParamsPersister.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,10 @@ class LaunchParamsPersister { } } void saveTask(Task task) { void saveTask(Task task) { saveTask(task, task.getDisplayContent()); } void saveTask(Task task, DisplayContent display) { final ComponentName name = task.realActivity; final ComponentName name = task.realActivity; final int userId = task.mUserId; final int userId = task.mUserId; PersistableLaunchParams params; PersistableLaunchParams params; Loading @@ -211,7 +215,7 @@ class LaunchParamsPersister { params = new PersistableLaunchParams(); params = new PersistableLaunchParams(); map.put(name, params); map.put(name, params); } } final boolean changed = saveTaskToLaunchParam(task, params); final boolean changed = saveTaskToLaunchParam(task, display, params); if (changed) { if (changed) { mPersisterQueue.updateLastOrAddItem( mPersisterQueue.updateLastOrAddItem( Loading @@ -220,17 +224,16 @@ class LaunchParamsPersister { } } } } private boolean saveTaskToLaunchParam(Task task, PersistableLaunchParams params) { private boolean saveTaskToLaunchParam( final ActivityStack stack = task.getStack(); Task task, DisplayContent display, PersistableLaunchParams params) { final DisplayContent display = stack.getDisplayContent(); final DisplayInfo info = new DisplayInfo(); final DisplayInfo info = new DisplayInfo(); display.mDisplay.getDisplayInfo(info); display.mDisplay.getDisplayInfo(info); boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId); boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId); params.mDisplayUniqueId = info.uniqueId; params.mDisplayUniqueId = info.uniqueId; changed |= params.mWindowingMode != stack.getWindowingMode(); changed |= params.mWindowingMode != task.getWindowingMode(); params.mWindowingMode = stack.getWindowingMode(); params.mWindowingMode = task.getWindowingMode(); if (task.mLastNonFullscreenBounds != null) { if (task.mLastNonFullscreenBounds != null) { changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds); changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds); Loading services/core/java/com/android/server/wm/Task.java +16 −7 Original line number Original line Diff line number Diff line Loading @@ -574,13 +574,19 @@ class Task extends WindowContainer<WindowContainer> { mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity); mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity); } } private void cleanUpResourcesForDestroy() { private void cleanUpResourcesForDestroy(ConfigurationContainer oldParent) { if (hasChild()) { if (hasChild()) { return; return; } } // TODO(xutan): Removed type check after stack and task is merged. // Before the real merge of stack and task, we need to avoid saving state of stacks. Once // the merge is finished we can just pass DisplayContent because both windowing mode and // bounds are set in the merged task. if (oldParent instanceof ActivityStack) { // This task is going away, so save the last state if necessary. // This task is going away, so save the last state if necessary. saveLaunchingStateIfNeeded(); saveLaunchingStateIfNeeded(((WindowContainer) oldParent).getDisplayContent()); } // TODO: VI what about activity? // TODO: VI what about activity? final boolean isVoiceSession = voiceSession != null; final boolean isVoiceSession = voiceSession != null; Loading Loading @@ -1053,9 +1059,8 @@ class Task extends WindowContainer<WindowContainer> { mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY; mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY; // Task is going to be removed, clean it up before detaching from hierarchy. if (oldParent != null && newParent == null) { if (oldParent != null && newParent == null) { cleanUpResourcesForDestroy(); cleanUpResourcesForDestroy(oldParent); } } if (display != null) { if (display != null) { Loading Loading @@ -1884,7 +1889,11 @@ class Task extends WindowContainer<WindowContainer> { * It only saves state if this task has been shown to user and it's in fullscreen or freeform * It only saves state if this task has been shown to user and it's in fullscreen or freeform * mode on freeform displays. * mode on freeform displays. */ */ void saveLaunchingStateIfNeeded() { private void saveLaunchingStateIfNeeded() { saveLaunchingStateIfNeeded(getDisplayContent()); } private void saveLaunchingStateIfNeeded(DisplayContent display) { if (!hasBeenVisible) { if (!hasBeenVisible) { // Not ever visible to user. // Not ever visible to user. return; return; Loading @@ -1904,7 +1913,7 @@ class Task extends WindowContainer<WindowContainer> { } } // Saves the new state so that we can launch the activity at the same location. // Saves the new state so that we can launch the activity at the same location. mStackSupervisor.mLaunchParamsPersister.saveTask(this); mStackSupervisor.mLaunchParamsPersister.saveTask(this, display); } } /** /** Loading services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { } } @Override @Override void saveTask(Task task) { void saveTask(Task task, DisplayContent display) { final int userId = task.mUserId; final int userId = task.mUserId; final ComponentName realActivity = task.realActivity; final ComponentName realActivity = task.realActivity; mTmpParams.mPreferredDisplayId = task.getDisplayId(); mTmpParams.mPreferredDisplayId = task.getDisplayId(); Loading services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +78 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; Loading @@ -34,6 +36,7 @@ import static android.view.Surface.ROTATION_90; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; Loading @@ -51,10 +54,13 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.TaskInfo; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.ComponentName; import android.content.Intent; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; Loading Loading @@ -859,6 +865,78 @@ public class TaskRecordTests extends ActivityTestsBase { verify(task).setIntent(eq(activity0)); verify(task).setIntent(eq(activity0)); } } @Test public void testSaveLaunchingStateWhenConfigurationChanged() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister).saveTask(task, task.getDisplayContent()); } @Test public void testSaveLaunchingStateWhenClearingParent() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); final DisplayContent oldDisplay = task.getDisplayContent(); LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams(); params.mWindowingMode = WINDOWING_MODE_UNDEFINED; persister.getLaunchParams(task, null, params); assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode); task.hasBeenVisible = true; task.removeImmediately(); verify(persister).saveTask(task, oldDisplay); persister.getLaunchParams(task, null, params); assertEquals(WINDOWING_MODE_FULLSCREEN, params.mWindowingMode); } @Test public void testNotSaveLaunchingStateNonFreeformDisplay() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister, never()).saveTask(same(task), any()); } @Test public void testNotSaveLaunchingStateWhenNotFullscreenOrFreeformWindow() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_PINNED); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister, never()).saveTask(same(task), any()); } private Task getTestTask() { private Task getTestTask() { final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); return stack.getBottomMostTask(); return stack.getBottomMostTask(); Loading Loading
services/core/java/com/android/server/wm/LaunchParamsPersister.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,10 @@ class LaunchParamsPersister { } } void saveTask(Task task) { void saveTask(Task task) { saveTask(task, task.getDisplayContent()); } void saveTask(Task task, DisplayContent display) { final ComponentName name = task.realActivity; final ComponentName name = task.realActivity; final int userId = task.mUserId; final int userId = task.mUserId; PersistableLaunchParams params; PersistableLaunchParams params; Loading @@ -211,7 +215,7 @@ class LaunchParamsPersister { params = new PersistableLaunchParams(); params = new PersistableLaunchParams(); map.put(name, params); map.put(name, params); } } final boolean changed = saveTaskToLaunchParam(task, params); final boolean changed = saveTaskToLaunchParam(task, display, params); if (changed) { if (changed) { mPersisterQueue.updateLastOrAddItem( mPersisterQueue.updateLastOrAddItem( Loading @@ -220,17 +224,16 @@ class LaunchParamsPersister { } } } } private boolean saveTaskToLaunchParam(Task task, PersistableLaunchParams params) { private boolean saveTaskToLaunchParam( final ActivityStack stack = task.getStack(); Task task, DisplayContent display, PersistableLaunchParams params) { final DisplayContent display = stack.getDisplayContent(); final DisplayInfo info = new DisplayInfo(); final DisplayInfo info = new DisplayInfo(); display.mDisplay.getDisplayInfo(info); display.mDisplay.getDisplayInfo(info); boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId); boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId); params.mDisplayUniqueId = info.uniqueId; params.mDisplayUniqueId = info.uniqueId; changed |= params.mWindowingMode != stack.getWindowingMode(); changed |= params.mWindowingMode != task.getWindowingMode(); params.mWindowingMode = stack.getWindowingMode(); params.mWindowingMode = task.getWindowingMode(); if (task.mLastNonFullscreenBounds != null) { if (task.mLastNonFullscreenBounds != null) { changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds); changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds); Loading
services/core/java/com/android/server/wm/Task.java +16 −7 Original line number Original line Diff line number Diff line Loading @@ -574,13 +574,19 @@ class Task extends WindowContainer<WindowContainer> { mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity); mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity); } } private void cleanUpResourcesForDestroy() { private void cleanUpResourcesForDestroy(ConfigurationContainer oldParent) { if (hasChild()) { if (hasChild()) { return; return; } } // TODO(xutan): Removed type check after stack and task is merged. // Before the real merge of stack and task, we need to avoid saving state of stacks. Once // the merge is finished we can just pass DisplayContent because both windowing mode and // bounds are set in the merged task. if (oldParent instanceof ActivityStack) { // This task is going away, so save the last state if necessary. // This task is going away, so save the last state if necessary. saveLaunchingStateIfNeeded(); saveLaunchingStateIfNeeded(((WindowContainer) oldParent).getDisplayContent()); } // TODO: VI what about activity? // TODO: VI what about activity? final boolean isVoiceSession = voiceSession != null; final boolean isVoiceSession = voiceSession != null; Loading Loading @@ -1053,9 +1059,8 @@ class Task extends WindowContainer<WindowContainer> { mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY; mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY; // Task is going to be removed, clean it up before detaching from hierarchy. if (oldParent != null && newParent == null) { if (oldParent != null && newParent == null) { cleanUpResourcesForDestroy(); cleanUpResourcesForDestroy(oldParent); } } if (display != null) { if (display != null) { Loading Loading @@ -1884,7 +1889,11 @@ class Task extends WindowContainer<WindowContainer> { * It only saves state if this task has been shown to user and it's in fullscreen or freeform * It only saves state if this task has been shown to user and it's in fullscreen or freeform * mode on freeform displays. * mode on freeform displays. */ */ void saveLaunchingStateIfNeeded() { private void saveLaunchingStateIfNeeded() { saveLaunchingStateIfNeeded(getDisplayContent()); } private void saveLaunchingStateIfNeeded(DisplayContent display) { if (!hasBeenVisible) { if (!hasBeenVisible) { // Not ever visible to user. // Not ever visible to user. return; return; Loading @@ -1904,7 +1913,7 @@ class Task extends WindowContainer<WindowContainer> { } } // Saves the new state so that we can launch the activity at the same location. // Saves the new state so that we can launch the activity at the same location. mStackSupervisor.mLaunchParamsPersister.saveTask(this); mStackSupervisor.mLaunchParamsPersister.saveTask(this, display); } } /** /** Loading
services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { } } @Override @Override void saveTask(Task task) { void saveTask(Task task, DisplayContent display) { final int userId = task.mUserId; final int userId = task.mUserId; final ComponentName realActivity = task.realActivity; final ComponentName realActivity = task.realActivity; mTmpParams.mPreferredDisplayId = task.getDisplayId(); mTmpParams.mPreferredDisplayId = task.getDisplayId(); Loading
services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +78 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; Loading @@ -34,6 +36,7 @@ import static android.view.Surface.ROTATION_90; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; Loading @@ -51,10 +54,13 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.TaskInfo; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.ComponentName; import android.content.Intent; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; Loading Loading @@ -859,6 +865,78 @@ public class TaskRecordTests extends ActivityTestsBase { verify(task).setIntent(eq(activity0)); verify(task).setIntent(eq(activity0)); } } @Test public void testSaveLaunchingStateWhenConfigurationChanged() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister).saveTask(task, task.getDisplayContent()); } @Test public void testSaveLaunchingStateWhenClearingParent() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); final DisplayContent oldDisplay = task.getDisplayContent(); LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams(); params.mWindowingMode = WINDOWING_MODE_UNDEFINED; persister.getLaunchParams(task, null, params); assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode); task.hasBeenVisible = true; task.removeImmediately(); verify(persister).saveTask(task, oldDisplay); persister.getLaunchParams(task, null, params); assertEquals(WINDOWING_MODE_FULLSCREEN, params.mWindowingMode); } @Test public void testNotSaveLaunchingStateNonFreeformDisplay() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister, never()).saveTask(same(task), any()); } @Test public void testNotSaveLaunchingStateWhenNotFullscreenOrFreeformWindow() { LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister; spyOn(persister); final Task task = getTestTask(); task.hasBeenVisible = false; task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM); task.getStack().setWindowingMode(WINDOWING_MODE_PINNED); task.hasBeenVisible = true; task.onConfigurationChanged(task.getParent().getConfiguration()); verify(persister, never()).saveTask(same(task), any()); } private Task getTestTask() { private Task getTestTask() { final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); return stack.getBottomMostTask(); return stack.getBottomMostTask(); Loading