Merge "[4/n] Pin ActivityStack" into udc-qpr-dev
This commit is contained in:
@@ -73,6 +73,13 @@ public final class TaskFragmentOperation implements Parcelable {
|
||||
/** Sets the relative bounds with {@link WindowContainerTransaction#setRelativeBounds}. */
|
||||
public static final int OP_TYPE_SET_RELATIVE_BOUNDS = 9;
|
||||
|
||||
/**
|
||||
* Reorders the TaskFragment to be the front-most TaskFragment in the Task.
|
||||
* Note that there could still have other WindowContainer on top of the front-most
|
||||
* TaskFragment, such as a non-embedded Activity.
|
||||
*/
|
||||
public static final int OP_TYPE_REORDER_TO_FRONT = 10;
|
||||
|
||||
@IntDef(prefix = { "OP_TYPE_" }, value = {
|
||||
OP_TYPE_UNKNOWN,
|
||||
OP_TYPE_CREATE_TASK_FRAGMENT,
|
||||
@@ -84,7 +91,8 @@ public final class TaskFragmentOperation implements Parcelable {
|
||||
OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT,
|
||||
OP_TYPE_SET_COMPANION_TASK_FRAGMENT,
|
||||
OP_TYPE_SET_ANIMATION_PARAMS,
|
||||
OP_TYPE_SET_RELATIVE_BOUNDS
|
||||
OP_TYPE_SET_RELATIVE_BOUNDS,
|
||||
OP_TYPE_REORDER_TO_FRONT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface OperationType {}
|
||||
|
||||
@@ -1621,6 +1621,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
// background.
|
||||
return;
|
||||
}
|
||||
final SplitContainer splitContainer = getActiveSplitForContainer(container);
|
||||
if (splitContainer instanceof SplitPinContainer
|
||||
&& updateSplitContainerIfNeeded(splitContainer, wct, null /* splitAttributes */)) {
|
||||
// A SplitPinContainer exists and is updated.
|
||||
return;
|
||||
}
|
||||
if (launchPlaceholderIfNecessary(wct, container)) {
|
||||
// Placeholder was launched, the positions will be updated when the activity is added
|
||||
// to the secondary container.
|
||||
@@ -1633,7 +1639,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
// If the info is not available yet the task fragment will be expanded when it's ready
|
||||
return;
|
||||
}
|
||||
SplitContainer splitContainer = getActiveSplitForContainer(container);
|
||||
if (splitContainer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package androidx.window.extensions.embedding;
|
||||
|
||||
import static android.content.pm.PackageManager.MATCH_ALL;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityThread;
|
||||
@@ -39,6 +40,7 @@ import android.view.WindowInsets;
|
||||
import android.view.WindowMetrics;
|
||||
import android.window.TaskFragmentAnimationParams;
|
||||
import android.window.TaskFragmentCreationParams;
|
||||
import android.window.TaskFragmentOperation;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
@@ -420,6 +422,16 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
container.setLastRequestedBounds(fragmentOptions.getInitialRelativeBounds());
|
||||
container.setLastRequestedWindowingMode(fragmentOptions.getWindowingMode());
|
||||
super.createTaskFragment(wct, fragmentOptions);
|
||||
|
||||
// Reorders the pinned TaskFragment to front to ensure it is the front-most TaskFragment.
|
||||
final SplitPinContainer pinnedContainer =
|
||||
container.getTaskContainer().getSplitPinContainer();
|
||||
if (pinnedContainer != null) {
|
||||
final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
|
||||
OP_TYPE_REORDER_TO_FRONT).build();
|
||||
wct.addTaskFragmentOperation(
|
||||
pinnedContainer.getSecondaryContainer().getTaskFragmentToken(), operation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -307,14 +307,14 @@ class TaskContainer {
|
||||
}
|
||||
|
||||
final TaskFragmentContainer pinnedContainer = mSplitPinContainer.getSecondaryContainer();
|
||||
final int index = mContainers.indexOf(pinnedContainer);
|
||||
if (index <= 0) {
|
||||
final int pinnedContainerIndex = mContainers.indexOf(pinnedContainer);
|
||||
if (pinnedContainerIndex <= 0) {
|
||||
removeSplitPinContainer();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the pinned container is top-most.
|
||||
if (index != mContainers.size() - 1) {
|
||||
if (pinnedContainerIndex != mContainers.size() - 1) {
|
||||
mContainers.remove(pinnedContainer);
|
||||
mContainers.add(pinnedContainer);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
|
||||
@@ -1335,6 +1336,19 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
taskFragment.setAnimationParams(animationParams);
|
||||
break;
|
||||
}
|
||||
case OP_TYPE_REORDER_TO_FRONT: {
|
||||
final Task task = taskFragment.getTask();
|
||||
if (task != null) {
|
||||
final TaskFragment topTaskFragment = task.getTaskFragment(
|
||||
tf -> tf.asTask() == null);
|
||||
if (topTaskFragment != null && topTaskFragment != taskFragment) {
|
||||
final int index = task.mChildren.indexOf(topTaskFragment);
|
||||
task.mChildren.remove(taskFragment);
|
||||
task.mChildren.add(index, taskFragment);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return effects;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
|
||||
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
|
||||
@@ -1590,6 +1591,46 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
assertEquals(taskFragmentBounds, mTaskFragment.getBounds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyTransaction_reorderTaskFragmentToFront() {
|
||||
final Task task = createTask(mDisplayContent);
|
||||
// Create a TaskFragment.
|
||||
final IBinder token0 = new Binder();
|
||||
final TaskFragment tf0 = new TaskFragmentBuilder(mAtm)
|
||||
.setParentTask(task)
|
||||
.setFragmentToken(token0)
|
||||
.setOrganizer(mOrganizer)
|
||||
.createActivityCount(1)
|
||||
.build();
|
||||
// Create another TaskFragment
|
||||
final IBinder token1 = new Binder();
|
||||
final TaskFragment tf1 = new TaskFragmentBuilder(mAtm)
|
||||
.setParentTask(task)
|
||||
.setFragmentToken(token1)
|
||||
.setOrganizer(mOrganizer)
|
||||
.createActivityCount(1)
|
||||
.build();
|
||||
// Create a non-embedded Activity on top.
|
||||
final ActivityRecord topActivity = new ActivityBuilder(mAtm)
|
||||
.setTask(task)
|
||||
.build();
|
||||
mWindowOrganizerController.mLaunchTaskFragments.put(token0, tf0);
|
||||
mWindowOrganizerController.mLaunchTaskFragments.put(token1, tf1);
|
||||
|
||||
// Reorder TaskFragment to front
|
||||
final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
|
||||
OP_TYPE_REORDER_TO_FRONT).build();
|
||||
mTransaction.addTaskFragmentOperation(token0, operation);
|
||||
assertApplyTransactionAllowed(mTransaction);
|
||||
|
||||
// Ensure the non-embedded activity still on top.
|
||||
assertEquals(topActivity, task.getTopChild().asActivityRecord());
|
||||
|
||||
// Ensure the TaskFragment is moved to front.
|
||||
final TaskFragment frontMostTaskFragment = task.getTaskFragment(tf -> tf.asTask() == null);
|
||||
assertEquals(frontMostTaskFragment, tf0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TaskFragment} with the {@link WindowContainerTransaction}. Calls
|
||||
* {@link WindowOrganizerController#applyTransaction(WindowContainerTransaction)} to apply the
|
||||
|
||||
Reference in New Issue
Block a user