Loading core/java/android/window/TaskFragmentOperation.java +42 −5 Original line number Diff line number Diff line Loading @@ -80,6 +80,14 @@ public final class TaskFragmentOperation implements Parcelable { */ public static final int OP_TYPE_REORDER_TO_FRONT = 10; /** * Sets the activity navigation to be isolated, where the activity navigation on the * TaskFragment is separated from the rest activities in the Task. Activities cannot be * started on an isolated TaskFragment unless the activities are launched from the same * TaskFragment or explicitly requested to. */ public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; @IntDef(prefix = { "OP_TYPE_" }, value = { OP_TYPE_UNKNOWN, OP_TYPE_CREATE_TASK_FRAGMENT, Loading @@ -92,7 +100,8 @@ public final class TaskFragmentOperation implements Parcelable { OP_TYPE_SET_COMPANION_TASK_FRAGMENT, OP_TYPE_SET_ANIMATION_PARAMS, OP_TYPE_SET_RELATIVE_BOUNDS, OP_TYPE_REORDER_TO_FRONT OP_TYPE_REORDER_TO_FRONT, OP_TYPE_SET_ISOLATED_NAVIGATION }) @Retention(RetentionPolicy.SOURCE) public @interface OperationType {} Loading @@ -118,11 +127,14 @@ public final class TaskFragmentOperation implements Parcelable { @Nullable private final TaskFragmentAnimationParams mAnimationParams; private final boolean mIsolatedNav; private TaskFragmentOperation(@OperationType int opType, @Nullable TaskFragmentCreationParams taskFragmentCreationParams, @Nullable IBinder activityToken, @Nullable Intent activityIntent, @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, @Nullable TaskFragmentAnimationParams animationParams) { @Nullable TaskFragmentAnimationParams animationParams, boolean isolatedNav) { mOpType = opType; mTaskFragmentCreationParams = taskFragmentCreationParams; mActivityToken = activityToken; Loading @@ -130,6 +142,7 @@ public final class TaskFragmentOperation implements Parcelable { mBundle = bundle; mSecondaryFragmentToken = secondaryFragmentToken; mAnimationParams = animationParams; mIsolatedNav = isolatedNav; } private TaskFragmentOperation(Parcel in) { Loading @@ -140,6 +153,7 @@ public final class TaskFragmentOperation implements Parcelable { mBundle = in.readBundle(getClass().getClassLoader()); mSecondaryFragmentToken = in.readStrongBinder(); mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR); mIsolatedNav = in.readBoolean(); } @Override Loading @@ -151,6 +165,7 @@ public final class TaskFragmentOperation implements Parcelable { dest.writeBundle(mBundle); dest.writeStrongBinder(mSecondaryFragmentToken); dest.writeTypedObject(mAnimationParams, flags); dest.writeBoolean(mIsolatedNav); } @NonNull Loading Loading @@ -223,6 +238,14 @@ public final class TaskFragmentOperation implements Parcelable { return mAnimationParams; } /** * Returns whether the activity navigation on this TaskFragment is isolated. This is only * useful when the op type is {@link OP_TYPE_SET_ISOLATED_NAVIGATION}. */ public boolean isIsolatedNav() { return mIsolatedNav; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); Loading @@ -245,6 +268,7 @@ public final class TaskFragmentOperation implements Parcelable { if (mAnimationParams != null) { sb.append(", animationParams=").append(mAnimationParams); } sb.append(", isolatedNav=").append(mIsolatedNav); sb.append('}'); return sb.toString(); Loading @@ -253,7 +277,7 @@ public final class TaskFragmentOperation implements Parcelable { @Override public int hashCode() { return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams); mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav); } @Override Loading @@ -268,7 +292,8 @@ public final class TaskFragmentOperation implements Parcelable { && Objects.equals(mActivityIntent, other.mActivityIntent) && Objects.equals(mBundle, other.mBundle) && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken) && Objects.equals(mAnimationParams, other.mAnimationParams); && Objects.equals(mAnimationParams, other.mAnimationParams) && mIsolatedNav == other.mIsolatedNav; } @Override Loading Loading @@ -300,6 +325,8 @@ public final class TaskFragmentOperation implements Parcelable { @Nullable private TaskFragmentAnimationParams mAnimationParams; private boolean mIsolatedNav; /** * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}. */ Loading Loading @@ -362,13 +389,23 @@ public final class TaskFragmentOperation implements Parcelable { return this; } /** * Sets the activity navigation of this TaskFragment to be isolated. */ @NonNull public Builder setIsolatedNav(boolean isolatedNav) { mIsolatedNav = isolatedNav; return this; } /** * Constructs the {@link TaskFragmentOperation}. */ @NonNull public TaskFragmentOperation build() { return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams); mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav); } } } libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +16 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,9 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -340,6 +342,20 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { wct.deleteTaskFragment(fragmentToken); } void reorderTaskFragmentToFront(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_REORDER_TO_FRONT).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean isolatedNav) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_SET_ISOLATED_NAVIGATION).setIsolatedNav(isolatedNav).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void updateTaskFragmentInfo(@NonNull TaskFragmentInfo taskFragmentInfo) { mFragmentInfos.put(taskFragmentInfo.getFragmentToken(), taskFragmentInfo); } Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +4 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Updates the Split final TransactionRecord transactionRecord = mTransactionManager.startNewTransaction(); final WindowContainerTransaction wct = transactionRecord.getTransaction(); mPresenter.setTaskFragmentIsolatedNavigation(wct, splitPinContainer.getSecondaryContainer().getTaskFragmentToken(), true /* isolatedNav */); mPresenter.updateSplitContainer(splitPinContainer, wct); transactionRecord.apply(false /* shouldApplyIndependently */); updateCallbackIfNecessary(); Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +2 −6 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ 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; Loading @@ -40,7 +39,6 @@ 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; Loading Loading @@ -427,10 +425,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { 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); reorderTaskFragmentToFront(wct, pinnedContainer.getSecondaryContainer().getTaskFragmentToken()); } } Loading services/core/java/com/android/server/wm/ActivityStarter.java +12 −1 Original line number Diff line number Diff line Loading @@ -3100,7 +3100,18 @@ class ActivityStarter { } else { TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; if (candidateTf == null) { final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */); // Puts the activity on the top-most non-isolated navigation TF, unless the // activity is launched from the same TF. final TaskFragment sourceTaskFragment = mSourceRecord != null ? mSourceRecord.getTaskFragment() : null; final ActivityRecord top = task.getActivity(r -> { if (!r.canBeTopRunning()) { return false; } final TaskFragment taskFragment = r.getTaskFragment(); return !taskFragment.isIsolatedNav() || (sourceTaskFragment != null && sourceTaskFragment == taskFragment); }); if (top != null) { candidateTf = top.getTaskFragment(); } Loading Loading
core/java/android/window/TaskFragmentOperation.java +42 −5 Original line number Diff line number Diff line Loading @@ -80,6 +80,14 @@ public final class TaskFragmentOperation implements Parcelable { */ public static final int OP_TYPE_REORDER_TO_FRONT = 10; /** * Sets the activity navigation to be isolated, where the activity navigation on the * TaskFragment is separated from the rest activities in the Task. Activities cannot be * started on an isolated TaskFragment unless the activities are launched from the same * TaskFragment or explicitly requested to. */ public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; @IntDef(prefix = { "OP_TYPE_" }, value = { OP_TYPE_UNKNOWN, OP_TYPE_CREATE_TASK_FRAGMENT, Loading @@ -92,7 +100,8 @@ public final class TaskFragmentOperation implements Parcelable { OP_TYPE_SET_COMPANION_TASK_FRAGMENT, OP_TYPE_SET_ANIMATION_PARAMS, OP_TYPE_SET_RELATIVE_BOUNDS, OP_TYPE_REORDER_TO_FRONT OP_TYPE_REORDER_TO_FRONT, OP_TYPE_SET_ISOLATED_NAVIGATION }) @Retention(RetentionPolicy.SOURCE) public @interface OperationType {} Loading @@ -118,11 +127,14 @@ public final class TaskFragmentOperation implements Parcelable { @Nullable private final TaskFragmentAnimationParams mAnimationParams; private final boolean mIsolatedNav; private TaskFragmentOperation(@OperationType int opType, @Nullable TaskFragmentCreationParams taskFragmentCreationParams, @Nullable IBinder activityToken, @Nullable Intent activityIntent, @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, @Nullable TaskFragmentAnimationParams animationParams) { @Nullable TaskFragmentAnimationParams animationParams, boolean isolatedNav) { mOpType = opType; mTaskFragmentCreationParams = taskFragmentCreationParams; mActivityToken = activityToken; Loading @@ -130,6 +142,7 @@ public final class TaskFragmentOperation implements Parcelable { mBundle = bundle; mSecondaryFragmentToken = secondaryFragmentToken; mAnimationParams = animationParams; mIsolatedNav = isolatedNav; } private TaskFragmentOperation(Parcel in) { Loading @@ -140,6 +153,7 @@ public final class TaskFragmentOperation implements Parcelable { mBundle = in.readBundle(getClass().getClassLoader()); mSecondaryFragmentToken = in.readStrongBinder(); mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR); mIsolatedNav = in.readBoolean(); } @Override Loading @@ -151,6 +165,7 @@ public final class TaskFragmentOperation implements Parcelable { dest.writeBundle(mBundle); dest.writeStrongBinder(mSecondaryFragmentToken); dest.writeTypedObject(mAnimationParams, flags); dest.writeBoolean(mIsolatedNav); } @NonNull Loading Loading @@ -223,6 +238,14 @@ public final class TaskFragmentOperation implements Parcelable { return mAnimationParams; } /** * Returns whether the activity navigation on this TaskFragment is isolated. This is only * useful when the op type is {@link OP_TYPE_SET_ISOLATED_NAVIGATION}. */ public boolean isIsolatedNav() { return mIsolatedNav; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); Loading @@ -245,6 +268,7 @@ public final class TaskFragmentOperation implements Parcelable { if (mAnimationParams != null) { sb.append(", animationParams=").append(mAnimationParams); } sb.append(", isolatedNav=").append(mIsolatedNav); sb.append('}'); return sb.toString(); Loading @@ -253,7 +277,7 @@ public final class TaskFragmentOperation implements Parcelable { @Override public int hashCode() { return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams); mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav); } @Override Loading @@ -268,7 +292,8 @@ public final class TaskFragmentOperation implements Parcelable { && Objects.equals(mActivityIntent, other.mActivityIntent) && Objects.equals(mBundle, other.mBundle) && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken) && Objects.equals(mAnimationParams, other.mAnimationParams); && Objects.equals(mAnimationParams, other.mAnimationParams) && mIsolatedNav == other.mIsolatedNav; } @Override Loading Loading @@ -300,6 +325,8 @@ public final class TaskFragmentOperation implements Parcelable { @Nullable private TaskFragmentAnimationParams mAnimationParams; private boolean mIsolatedNav; /** * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}. */ Loading Loading @@ -362,13 +389,23 @@ public final class TaskFragmentOperation implements Parcelable { return this; } /** * Sets the activity navigation of this TaskFragment to be isolated. */ @NonNull public Builder setIsolatedNav(boolean isolatedNav) { mIsolatedNav = isolatedNav; return this; } /** * Constructs the {@link TaskFragmentOperation}. */ @NonNull public TaskFragmentOperation build() { return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams); mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav); } } }
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +16 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,9 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -340,6 +342,20 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { wct.deleteTaskFragment(fragmentToken); } void reorderTaskFragmentToFront(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_REORDER_TO_FRONT).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean isolatedNav) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_SET_ISOLATED_NAVIGATION).setIsolatedNav(isolatedNav).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void updateTaskFragmentInfo(@NonNull TaskFragmentInfo taskFragmentInfo) { mFragmentInfos.put(taskFragmentInfo.getFragmentToken(), taskFragmentInfo); } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +4 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Updates the Split final TransactionRecord transactionRecord = mTransactionManager.startNewTransaction(); final WindowContainerTransaction wct = transactionRecord.getTransaction(); mPresenter.setTaskFragmentIsolatedNavigation(wct, splitPinContainer.getSecondaryContainer().getTaskFragmentToken(), true /* isolatedNav */); mPresenter.updateSplitContainer(splitPinContainer, wct); transactionRecord.apply(false /* shouldApplyIndependently */); updateCallbackIfNecessary(); Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +2 −6 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ 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; Loading @@ -40,7 +39,6 @@ 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; Loading Loading @@ -427,10 +425,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { 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); reorderTaskFragmentToFront(wct, pinnedContainer.getSecondaryContainer().getTaskFragmentToken()); } } Loading
services/core/java/com/android/server/wm/ActivityStarter.java +12 −1 Original line number Diff line number Diff line Loading @@ -3100,7 +3100,18 @@ class ActivityStarter { } else { TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; if (candidateTf == null) { final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */); // Puts the activity on the top-most non-isolated navigation TF, unless the // activity is launched from the same TF. final TaskFragment sourceTaskFragment = mSourceRecord != null ? mSourceRecord.getTaskFragment() : null; final ActivityRecord top = task.getActivity(r -> { if (!r.canBeTopRunning()) { return false; } final TaskFragment taskFragment = r.getTaskFragment(); return !taskFragment.isIsolatedNav() || (sourceTaskFragment != null && sourceTaskFragment == taskFragment); }); if (top != null) { candidateTf = top.getTaskFragment(); } Loading