Merge "Move Task Close to WindowContainerTransaction" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ef023c1411
@@ -3398,6 +3398,7 @@ package android.window {
|
||||
method @NonNull public android.window.WindowContainerTransaction createTaskFragment(@NonNull android.window.TaskFragmentCreationParams);
|
||||
method @NonNull public android.window.WindowContainerTransaction deleteTaskFragment(@NonNull android.window.WindowContainerToken);
|
||||
method public int describeContents();
|
||||
method @NonNull public android.window.WindowContainerTransaction removeTask(@NonNull android.window.WindowContainerToken);
|
||||
method @NonNull public android.window.WindowContainerTransaction reorder(@NonNull android.window.WindowContainerToken, boolean);
|
||||
method @NonNull public android.window.WindowContainerTransaction reparent(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, boolean);
|
||||
method @NonNull public android.window.WindowContainerTransaction reparentActivityToTaskFragment(@NonNull android.os.IBinder, @NonNull android.os.IBinder);
|
||||
|
||||
@@ -455,6 +455,17 @@ public final class WindowContainerTransaction implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and removes a task and its children using its container token. The task is removed
|
||||
* from recents.
|
||||
* @param containerToken ContainerToken of Task to be removed
|
||||
*/
|
||||
@NonNull
|
||||
public WindowContainerTransaction removeTask(@NonNull WindowContainerToken containerToken) {
|
||||
mHierarchyOps.add(HierarchyOp.createForRemoveTask(containerToken.asBinder()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a pending intent in sync.
|
||||
* @param sender The PendingIntent sender.
|
||||
@@ -1153,6 +1164,7 @@ public final class WindowContainerTransaction implements Parcelable {
|
||||
public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
|
||||
public static final int HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 18;
|
||||
public static final int HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP = 19;
|
||||
public static final int HIERARCHY_OP_TYPE_REMOVE_TASK = 20;
|
||||
|
||||
// The following key(s) are for use with mLaunchOptions:
|
||||
// When launching a task (eg. from recents), this is the taskId to be launched.
|
||||
@@ -1282,6 +1294,13 @@ public final class WindowContainerTransaction implements Parcelable {
|
||||
.build();
|
||||
}
|
||||
|
||||
/** create a hierarchy op for deleting a task **/
|
||||
public static HierarchyOp createForRemoveTask(@NonNull IBinder container) {
|
||||
return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REMOVE_TASK)
|
||||
.setContainer(container)
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Only creates through {@link Builder}. */
|
||||
private HierarchyOp(int type) {
|
||||
mType = type;
|
||||
@@ -1465,6 +1484,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
||||
case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP:
|
||||
return "{setAlwaysOnTop: container=" + mContainer
|
||||
+ " alwaysOnTop=" + mAlwaysOnTop + "}";
|
||||
case HIERARCHY_OP_TYPE_REMOVE_TASK:
|
||||
return "{RemoveTask: task=" + mContainer + "}";
|
||||
default:
|
||||
return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
|
||||
+ " mToTop=" + mToTop
|
||||
|
||||
@@ -91,6 +91,12 @@ public class FreeformTaskTransitionHandler
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startRemoveTransition(WindowContainerTransaction wct) {
|
||||
final int type = WindowManager.TRANSIT_CLOSE;
|
||||
mPendingTransitionTokens.add(mTransitions.startTransition(type, wct, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||
@NonNull SurfaceControl.Transaction startT,
|
||||
|
||||
@@ -40,4 +40,12 @@ public interface FreeformTaskTransitionStarter {
|
||||
*
|
||||
*/
|
||||
void startMinimizedModeTransition(WindowContainerTransaction wct);
|
||||
|
||||
/**
|
||||
* Starts close window transition
|
||||
*
|
||||
* @param wct the {@link WindowContainerTransaction} that closes the task
|
||||
*
|
||||
*/
|
||||
void startRemoveTransition(WindowContainerTransaction wct);
|
||||
}
|
||||
@@ -148,7 +148,13 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption
|
||||
public void onClick(View v) {
|
||||
final int id = v.getId();
|
||||
if (id == R.id.close_window) {
|
||||
mActivityTaskManager.removeTask(mTaskId);
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.removeTask(mTaskToken);
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
mTransitionStarter.startRemoveTransition(wct);
|
||||
} else {
|
||||
mSyncQueue.queue(wct);
|
||||
}
|
||||
} else if (id == R.id.maximize_window) {
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
|
||||
|
||||
@@ -29,6 +29,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_TASK;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
|
||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
|
||||
@@ -703,6 +704,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
@Nullable ITaskFragmentOrganizer organizer, @Nullable Transition finishTransition) {
|
||||
final int type = hop.getType();
|
||||
switch (type) {
|
||||
case HIERARCHY_OP_TYPE_REMOVE_TASK: {
|
||||
final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
|
||||
final Task task = wc != null ? wc.asTask() : null;
|
||||
task.remove(true, "Applying remove task Hierarchy Op");
|
||||
break;
|
||||
}
|
||||
case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
|
||||
final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
|
||||
final Task task = wc != null ? wc.asTask() : null;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Test class for {@link WindowContainerTransaction}.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* atest WmTests:WindowContainerTransactionTests
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(WindowTestRunner.class)
|
||||
public class WindowContainerTransactionTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testRemoveTask() {
|
||||
final Task rootTask = createTask(mDisplayContent);
|
||||
final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
|
||||
final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
|
||||
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
WindowContainerToken token = task.getTaskInfo().token;
|
||||
wct.removeTask(token);
|
||||
applyTransaction(wct);
|
||||
|
||||
// There is still an activity to be destroyed, so the task is not removed immediately.
|
||||
assertNotNull(task.getParent());
|
||||
assertTrue(rootTask.hasChild());
|
||||
assertTrue(task.hasChild());
|
||||
assertTrue(activity.finishing);
|
||||
|
||||
activity.destroyed("testRemoveContainer");
|
||||
// Assert that the container was removed after the activity is destroyed.
|
||||
assertNull(task.getParent());
|
||||
assertEquals(0, task.getChildCount());
|
||||
assertNull(activity.getParent());
|
||||
verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(task);
|
||||
verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask);
|
||||
}
|
||||
|
||||
private Task createTask(int taskId) {
|
||||
return new Task.Builder(mAtm)
|
||||
.setTaskId(taskId)
|
||||
.setIntent(new Intent())
|
||||
.setRealActivity(ActivityBuilder.getDefaultComponent())
|
||||
.setEffectiveUid(10050)
|
||||
.buildInner();
|
||||
}
|
||||
|
||||
private void applyTransaction(@NonNull WindowContainerTransaction t) {
|
||||
if (!t.isEmpty()) {
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user