Loading core/java/android/app/Activity.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -8260,6 +8260,11 @@ public class Activity extends ContextThemeWrapper return mMainThread; return mMainThread; } } /** @hide */ public final ActivityInfo getActivityInfo() { return mActivityInfo; } final void performCreate(Bundle icicle) { final void performCreate(Bundle icicle) { performCreate(icicle, null); performCreate(icicle, null); } } Loading core/java/android/window/TaskFragmentInfo.java +42 −6 Original line number Original line Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading Loading @@ -66,7 +68,7 @@ public final class TaskFragmentInfo implements Parcelable { private final List<IBinder> mActivities = new ArrayList<>(); private final List<IBinder> mActivities = new ArrayList<>(); /** Relative position of the fragment's top left corner in the parent container. */ /** Relative position of the fragment's top left corner in the parent container. */ private final Point mPositionInParent; private final Point mPositionInParent = new Point(); /** /** * Whether the last running activity in the TaskFragment was finished due to clearing task while * Whether the last running activity in the TaskFragment was finished due to clearing task while Loading @@ -80,21 +82,31 @@ public final class TaskFragmentInfo implements Parcelable { */ */ private final boolean mIsTaskFragmentClearedForPip; private final boolean mIsTaskFragmentClearedForPip; /** * The maximum {@link ActivityInfo.WindowLayout#minWidth} and * {@link ActivityInfo.WindowLayout#minHeight} aggregated from the TaskFragment's child * activities. */ @NonNull private final Point mMinimumDimensions = new Point(); /** @hide */ /** @hide */ public TaskFragmentInfo( public TaskFragmentInfo( @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, int runningActivityCount, @NonNull Configuration configuration, int runningActivityCount, boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent, boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent, boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip) { boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip, @NonNull Point minimumDimensions) { mFragmentToken = requireNonNull(fragmentToken); mFragmentToken = requireNonNull(fragmentToken); mToken = requireNonNull(token); mToken = requireNonNull(token); mConfiguration.setTo(configuration); mConfiguration.setTo(configuration); mRunningActivityCount = runningActivityCount; mRunningActivityCount = runningActivityCount; mIsVisible = isVisible; mIsVisible = isVisible; mActivities.addAll(activities); mActivities.addAll(activities); mPositionInParent = requireNonNull(positionInParent); mPositionInParent.set(positionInParent); mIsTaskClearedForReuse = isTaskClearedForReuse; mIsTaskClearedForReuse = isTaskClearedForReuse; mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip; mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip; mMinimumDimensions.set(minimumDimensions); } } @NonNull @NonNull Loading Loading @@ -153,6 +165,26 @@ public final class TaskFragmentInfo implements Parcelable { return mConfiguration.windowConfiguration.getWindowingMode(); return mConfiguration.windowConfiguration.getWindowingMode(); } } /** * Returns the minimum width this TaskFragment can be resized to. * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)} * that {@link Rect#width()} is shorter than the reported value. * @hide pending unhide */ public int getMinimumWidth() { return mMinimumDimensions.x; } /** * Returns the minimum width this TaskFragment can be resized to. * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)} * that {@link Rect#height()} is shorter than the reported value. * @hide pending unhide */ public int getMinimumHeight() { return mMinimumDimensions.y; } /** /** * Returns {@code true} if the parameters that are important for task fragment organizers are * Returns {@code true} if the parameters that are important for task fragment organizers are * equal between this {@link TaskFragmentInfo} and {@param that}. * equal between this {@link TaskFragmentInfo} and {@param that}. Loading @@ -170,7 +202,8 @@ public final class TaskFragmentInfo implements Parcelable { && mActivities.equals(that.mActivities) && mActivities.equals(that.mActivities) && mPositionInParent.equals(that.mPositionInParent) && mPositionInParent.equals(that.mPositionInParent) && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip; && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip && mMinimumDimensions.equals(that.mMinimumDimensions); } } private TaskFragmentInfo(Parcel in) { private TaskFragmentInfo(Parcel in) { Loading @@ -180,9 +213,10 @@ public final class TaskFragmentInfo implements Parcelable { mRunningActivityCount = in.readInt(); mRunningActivityCount = in.readInt(); mIsVisible = in.readBoolean(); mIsVisible = in.readBoolean(); in.readBinderList(mActivities); in.readBinderList(mActivities); mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR)); mPositionInParent.readFromParcel(in); mIsTaskClearedForReuse = in.readBoolean(); mIsTaskClearedForReuse = in.readBoolean(); mIsTaskFragmentClearedForPip = in.readBoolean(); mIsTaskFragmentClearedForPip = in.readBoolean(); mMinimumDimensions.readFromParcel(in); } } /** @hide */ /** @hide */ Loading @@ -194,9 +228,10 @@ public final class TaskFragmentInfo implements Parcelable { dest.writeInt(mRunningActivityCount); dest.writeInt(mRunningActivityCount); dest.writeBoolean(mIsVisible); dest.writeBoolean(mIsVisible); dest.writeBinderList(mActivities); dest.writeBinderList(mActivities); dest.writeTypedObject(mPositionInParent, flags); mPositionInParent.writeToParcel(dest, flags); dest.writeBoolean(mIsTaskClearedForReuse); dest.writeBoolean(mIsTaskClearedForReuse); dest.writeBoolean(mIsTaskFragmentClearedForPip); dest.writeBoolean(mIsTaskFragmentClearedForPip); mMinimumDimensions.writeToParcel(dest, flags); } } @NonNull @NonNull Loading Loading @@ -224,6 +259,7 @@ public final class TaskFragmentInfo implements Parcelable { + " positionInParent=" + mPositionInParent + " positionInParent=" + mPositionInParent + " isTaskClearedForReuse=" + mIsTaskClearedForReuse + " isTaskClearedForReuse=" + mIsTaskClearedForReuse + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip + " minimumDimensions" + mMinimumDimensions + "}"; + "}"; } } Loading graphics/java/android/graphics/Point.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -36,8 +36,7 @@ public class Point implements Parcelable { } } public Point(@NonNull Point src) { public Point(@NonNull Point src) { this.x = src.x; set(src); this.y = src.y; } } /** /** Loading @@ -48,6 +47,15 @@ public class Point implements Parcelable { this.y = y; this.y = y; } } /** * Sets the point's from {@code src}'s coordinates * @hide */ public void set(@NonNull Point src) { this.x = src.x; this.y = src.y; } /** /** * Negate the point's coordinates * Negate the point's coordinates */ */ Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ package androidx.window.extensions.embedding; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.Activity; import android.app.Activity; import android.util.Pair; import android.util.Size; /** /** * Client-side descriptor of a split that holds two containers. * Client-side descriptor of a split that holds two containers. Loading Loading @@ -66,6 +68,13 @@ class SplitContainer { return mSplitRule; return mSplitRule; } } /** Returns the minimum dimension pair of primary container and secondary container. */ @NonNull Pair<Size, Size> getMinDimensionsPair() { return new Pair<>(mPrimaryContainer.getMinDimensions(), mSecondaryContainer.getMinDimensions()); } boolean isPlaceholderContainer() { boolean isPlaceholderContainer() { return (mSplitRule instanceof SplitPlaceholderRule); return (mSplitRule instanceof SplitPlaceholderRule); } } Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +30 −10 Original line number Original line Diff line number Diff line Loading @@ -24,9 +24,11 @@ import static androidx.window.extensions.embedding.SplitContainer.getFinishSecon import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitPresenter.boundsSmallerThanMinDimensions; import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair; import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.Activity; import android.app.ActivityClient; import android.app.ActivityClient; import android.app.ActivityOptions; import android.app.ActivityOptions; Loading @@ -43,11 +45,15 @@ import android.os.IBinder; import android.os.Looper; import android.os.Looper; import android.util.ArraySet; import android.util.ArraySet; import android.util.Log; import android.util.Log; import android.util.Pair; import android.util.Size; import android.util.SparseArray; import android.util.SparseArray; import android.window.TaskFragmentInfo; import android.window.TaskFragmentInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.GuardedBy; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.window.common.EmptyLifecycleCallbacksAdapter; import androidx.window.common.EmptyLifecycleCallbacksAdapter; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; Loading @@ -63,7 +69,7 @@ import java.util.function.Consumer; */ */ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, ActivityEmbeddingComponent { ActivityEmbeddingComponent { private static final String TAG = "SplitController"; static final String TAG = "SplitController"; @VisibleForTesting @VisibleForTesting @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -350,7 +356,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (!(rule instanceof SplitRule)) { if (!(rule instanceof SplitRule)) { continue; continue; } } if (mPresenter.shouldShowSideBySide(taskContainer.getTaskBounds(), (SplitRule) rule)) { if (shouldShowSideBySide(taskContainer.getTaskBounds(), (SplitRule) rule)) { return true; return true; } } } } Loading Loading @@ -614,12 +620,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Can launch in the existing secondary container if the rules share the same // Can launch in the existing secondary container if the rules share the same // presentation. // presentation. final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); if (secondaryContainer == getContainerWithActivity(secondaryActivity)) { if (secondaryContainer == getContainerWithActivity(secondaryActivity) && !boundsSmallerThanMinDimensions(secondaryContainer.getLastRequestedBounds(), getMinDimensions(secondaryActivity))) { // The activity is already in the target TaskFragment. // The activity is already in the target TaskFragment. return true; return true; } } secondaryContainer.addPendingAppearedActivity(secondaryActivity); secondaryContainer.addPendingAppearedActivity(secondaryActivity); final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, secondaryActivity, null /* secondaryIntent */); wct.reparentActivityToTaskFragment( wct.reparentActivityToTaskFragment( secondaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), secondaryActivity.getActivityToken()); secondaryActivity.getActivityToken()); Loading Loading @@ -791,6 +801,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen && (canReuseContainer(splitRule, splitContainer.getSplitRule()) && (canReuseContainer(splitRule, splitContainer.getSplitRule()) // TODO(b/231845476) we should always respect clearTop. // TODO(b/231845476) we should always respect clearTop. || !respectClearTop)) { || !respectClearTop)) { mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, null /* secondaryActivity */, intent); // Can launch in the existing secondary container if the rules share the same // Can launch in the existing secondary container if the rules share the same // presentation. // presentation. return splitContainer.getSecondaryContainer(); return splitContainer.getSecondaryContainer(); Loading Loading @@ -1117,8 +1129,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Check if there is enough space for launch // Check if there is enough space for launch final SplitPlaceholderRule placeholderRule = getPlaceholderRule(activity); final SplitPlaceholderRule placeholderRule = getPlaceholderRule(activity); if (placeholderRule == null || !mPresenter.shouldShowSideBySide( mPresenter.getParentContainerBounds(activity), placeholderRule)) { if (placeholderRule == null) { return false; } final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(activity, placeholderRule.getPlaceholderIntent()); if (!shouldShowSideBySide( mPresenter.getParentContainerBounds(activity), placeholderRule, minDimensionsPair)) { return false; return false; } } Loading Loading @@ -1161,7 +1181,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return false; return false; } } if (mPresenter.shouldShowSideBySide(splitContainer)) { if (shouldShowSideBySide(splitContainer)) { return false; return false; } } Loading Loading @@ -1233,7 +1253,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Splits that are not showing side-by-side are reported as having 0 split // Splits that are not showing side-by-side are reported as having 0 split // ratio, since by definition in the API the primary container occupies no // ratio, since by definition in the API the primary container occupies no // width of the split when covered by the secondary. // width of the split when covered by the secondary. mPresenter.shouldShowSideBySide(container) shouldShowSideBySide(container) ? container.getSplitRule().getSplitRatio() ? container.getSplitRule().getSplitRatio() : 0.0f); : 0.0f); splitStates.add(splitState); splitStates.add(splitState); Loading Loading @@ -1402,7 +1422,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } // Decide whether the associated container should be retained based on the current // Decide whether the associated container should be retained based on the current // presentation mode. // presentation mode. if (mPresenter.shouldShowSideBySide(splitContainer)) { if (shouldShowSideBySide(splitContainer)) { return !shouldFinishAssociatedContainerWhenAdjacent(finishBehavior); return !shouldFinishAssociatedContainerWhenAdjacent(finishBehavior); } else { } else { return !shouldFinishAssociatedContainerWhenStacked(finishBehavior); return !shouldFinishAssociatedContainerWhenStacked(finishBehavior); Loading Loading
core/java/android/app/Activity.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -8260,6 +8260,11 @@ public class Activity extends ContextThemeWrapper return mMainThread; return mMainThread; } } /** @hide */ public final ActivityInfo getActivityInfo() { return mActivityInfo; } final void performCreate(Bundle icicle) { final void performCreate(Bundle icicle) { performCreate(icicle, null); performCreate(icicle, null); } } Loading
core/java/android/window/TaskFragmentInfo.java +42 −6 Original line number Original line Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading Loading @@ -66,7 +68,7 @@ public final class TaskFragmentInfo implements Parcelable { private final List<IBinder> mActivities = new ArrayList<>(); private final List<IBinder> mActivities = new ArrayList<>(); /** Relative position of the fragment's top left corner in the parent container. */ /** Relative position of the fragment's top left corner in the parent container. */ private final Point mPositionInParent; private final Point mPositionInParent = new Point(); /** /** * Whether the last running activity in the TaskFragment was finished due to clearing task while * Whether the last running activity in the TaskFragment was finished due to clearing task while Loading @@ -80,21 +82,31 @@ public final class TaskFragmentInfo implements Parcelable { */ */ private final boolean mIsTaskFragmentClearedForPip; private final boolean mIsTaskFragmentClearedForPip; /** * The maximum {@link ActivityInfo.WindowLayout#minWidth} and * {@link ActivityInfo.WindowLayout#minHeight} aggregated from the TaskFragment's child * activities. */ @NonNull private final Point mMinimumDimensions = new Point(); /** @hide */ /** @hide */ public TaskFragmentInfo( public TaskFragmentInfo( @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, int runningActivityCount, @NonNull Configuration configuration, int runningActivityCount, boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent, boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent, boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip) { boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip, @NonNull Point minimumDimensions) { mFragmentToken = requireNonNull(fragmentToken); mFragmentToken = requireNonNull(fragmentToken); mToken = requireNonNull(token); mToken = requireNonNull(token); mConfiguration.setTo(configuration); mConfiguration.setTo(configuration); mRunningActivityCount = runningActivityCount; mRunningActivityCount = runningActivityCount; mIsVisible = isVisible; mIsVisible = isVisible; mActivities.addAll(activities); mActivities.addAll(activities); mPositionInParent = requireNonNull(positionInParent); mPositionInParent.set(positionInParent); mIsTaskClearedForReuse = isTaskClearedForReuse; mIsTaskClearedForReuse = isTaskClearedForReuse; mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip; mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip; mMinimumDimensions.set(minimumDimensions); } } @NonNull @NonNull Loading Loading @@ -153,6 +165,26 @@ public final class TaskFragmentInfo implements Parcelable { return mConfiguration.windowConfiguration.getWindowingMode(); return mConfiguration.windowConfiguration.getWindowingMode(); } } /** * Returns the minimum width this TaskFragment can be resized to. * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)} * that {@link Rect#width()} is shorter than the reported value. * @hide pending unhide */ public int getMinimumWidth() { return mMinimumDimensions.x; } /** * Returns the minimum width this TaskFragment can be resized to. * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)} * that {@link Rect#height()} is shorter than the reported value. * @hide pending unhide */ public int getMinimumHeight() { return mMinimumDimensions.y; } /** /** * Returns {@code true} if the parameters that are important for task fragment organizers are * Returns {@code true} if the parameters that are important for task fragment organizers are * equal between this {@link TaskFragmentInfo} and {@param that}. * equal between this {@link TaskFragmentInfo} and {@param that}. Loading @@ -170,7 +202,8 @@ public final class TaskFragmentInfo implements Parcelable { && mActivities.equals(that.mActivities) && mActivities.equals(that.mActivities) && mPositionInParent.equals(that.mPositionInParent) && mPositionInParent.equals(that.mPositionInParent) && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip; && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip && mMinimumDimensions.equals(that.mMinimumDimensions); } } private TaskFragmentInfo(Parcel in) { private TaskFragmentInfo(Parcel in) { Loading @@ -180,9 +213,10 @@ public final class TaskFragmentInfo implements Parcelable { mRunningActivityCount = in.readInt(); mRunningActivityCount = in.readInt(); mIsVisible = in.readBoolean(); mIsVisible = in.readBoolean(); in.readBinderList(mActivities); in.readBinderList(mActivities); mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR)); mPositionInParent.readFromParcel(in); mIsTaskClearedForReuse = in.readBoolean(); mIsTaskClearedForReuse = in.readBoolean(); mIsTaskFragmentClearedForPip = in.readBoolean(); mIsTaskFragmentClearedForPip = in.readBoolean(); mMinimumDimensions.readFromParcel(in); } } /** @hide */ /** @hide */ Loading @@ -194,9 +228,10 @@ public final class TaskFragmentInfo implements Parcelable { dest.writeInt(mRunningActivityCount); dest.writeInt(mRunningActivityCount); dest.writeBoolean(mIsVisible); dest.writeBoolean(mIsVisible); dest.writeBinderList(mActivities); dest.writeBinderList(mActivities); dest.writeTypedObject(mPositionInParent, flags); mPositionInParent.writeToParcel(dest, flags); dest.writeBoolean(mIsTaskClearedForReuse); dest.writeBoolean(mIsTaskClearedForReuse); dest.writeBoolean(mIsTaskFragmentClearedForPip); dest.writeBoolean(mIsTaskFragmentClearedForPip); mMinimumDimensions.writeToParcel(dest, flags); } } @NonNull @NonNull Loading Loading @@ -224,6 +259,7 @@ public final class TaskFragmentInfo implements Parcelable { + " positionInParent=" + mPositionInParent + " positionInParent=" + mPositionInParent + " isTaskClearedForReuse=" + mIsTaskClearedForReuse + " isTaskClearedForReuse=" + mIsTaskClearedForReuse + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip + " minimumDimensions" + mMinimumDimensions + "}"; + "}"; } } Loading
graphics/java/android/graphics/Point.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -36,8 +36,7 @@ public class Point implements Parcelable { } } public Point(@NonNull Point src) { public Point(@NonNull Point src) { this.x = src.x; set(src); this.y = src.y; } } /** /** Loading @@ -48,6 +47,15 @@ public class Point implements Parcelable { this.y = y; this.y = y; } } /** * Sets the point's from {@code src}'s coordinates * @hide */ public void set(@NonNull Point src) { this.x = src.x; this.y = src.y; } /** /** * Negate the point's coordinates * Negate the point's coordinates */ */ Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ package androidx.window.extensions.embedding; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.Activity; import android.app.Activity; import android.util.Pair; import android.util.Size; /** /** * Client-side descriptor of a split that holds two containers. * Client-side descriptor of a split that holds two containers. Loading Loading @@ -66,6 +68,13 @@ class SplitContainer { return mSplitRule; return mSplitRule; } } /** Returns the minimum dimension pair of primary container and secondary container. */ @NonNull Pair<Size, Size> getMinDimensionsPair() { return new Pair<>(mPrimaryContainer.getMinDimensions(), mSecondaryContainer.getMinDimensions()); } boolean isPlaceholderContainer() { boolean isPlaceholderContainer() { return (mSplitRule instanceof SplitPlaceholderRule); return (mSplitRule instanceof SplitPlaceholderRule); } } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +30 −10 Original line number Original line Diff line number Diff line Loading @@ -24,9 +24,11 @@ import static androidx.window.extensions.embedding.SplitContainer.getFinishSecon import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitPresenter.boundsSmallerThanMinDimensions; import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair; import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.Activity; import android.app.ActivityClient; import android.app.ActivityClient; import android.app.ActivityOptions; import android.app.ActivityOptions; Loading @@ -43,11 +45,15 @@ import android.os.IBinder; import android.os.Looper; import android.os.Looper; import android.util.ArraySet; import android.util.ArraySet; import android.util.Log; import android.util.Log; import android.util.Pair; import android.util.Size; import android.util.SparseArray; import android.util.SparseArray; import android.window.TaskFragmentInfo; import android.window.TaskFragmentInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.GuardedBy; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.window.common.EmptyLifecycleCallbacksAdapter; import androidx.window.common.EmptyLifecycleCallbacksAdapter; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; Loading @@ -63,7 +69,7 @@ import java.util.function.Consumer; */ */ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, ActivityEmbeddingComponent { ActivityEmbeddingComponent { private static final String TAG = "SplitController"; static final String TAG = "SplitController"; @VisibleForTesting @VisibleForTesting @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -350,7 +356,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (!(rule instanceof SplitRule)) { if (!(rule instanceof SplitRule)) { continue; continue; } } if (mPresenter.shouldShowSideBySide(taskContainer.getTaskBounds(), (SplitRule) rule)) { if (shouldShowSideBySide(taskContainer.getTaskBounds(), (SplitRule) rule)) { return true; return true; } } } } Loading Loading @@ -614,12 +620,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Can launch in the existing secondary container if the rules share the same // Can launch in the existing secondary container if the rules share the same // presentation. // presentation. final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); if (secondaryContainer == getContainerWithActivity(secondaryActivity)) { if (secondaryContainer == getContainerWithActivity(secondaryActivity) && !boundsSmallerThanMinDimensions(secondaryContainer.getLastRequestedBounds(), getMinDimensions(secondaryActivity))) { // The activity is already in the target TaskFragment. // The activity is already in the target TaskFragment. return true; return true; } } secondaryContainer.addPendingAppearedActivity(secondaryActivity); secondaryContainer.addPendingAppearedActivity(secondaryActivity); final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, secondaryActivity, null /* secondaryIntent */); wct.reparentActivityToTaskFragment( wct.reparentActivityToTaskFragment( secondaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), secondaryActivity.getActivityToken()); secondaryActivity.getActivityToken()); Loading Loading @@ -791,6 +801,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen && (canReuseContainer(splitRule, splitContainer.getSplitRule()) && (canReuseContainer(splitRule, splitContainer.getSplitRule()) // TODO(b/231845476) we should always respect clearTop. // TODO(b/231845476) we should always respect clearTop. || !respectClearTop)) { || !respectClearTop)) { mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, null /* secondaryActivity */, intent); // Can launch in the existing secondary container if the rules share the same // Can launch in the existing secondary container if the rules share the same // presentation. // presentation. return splitContainer.getSecondaryContainer(); return splitContainer.getSecondaryContainer(); Loading Loading @@ -1117,8 +1129,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Check if there is enough space for launch // Check if there is enough space for launch final SplitPlaceholderRule placeholderRule = getPlaceholderRule(activity); final SplitPlaceholderRule placeholderRule = getPlaceholderRule(activity); if (placeholderRule == null || !mPresenter.shouldShowSideBySide( mPresenter.getParentContainerBounds(activity), placeholderRule)) { if (placeholderRule == null) { return false; } final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(activity, placeholderRule.getPlaceholderIntent()); if (!shouldShowSideBySide( mPresenter.getParentContainerBounds(activity), placeholderRule, minDimensionsPair)) { return false; return false; } } Loading Loading @@ -1161,7 +1181,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return false; return false; } } if (mPresenter.shouldShowSideBySide(splitContainer)) { if (shouldShowSideBySide(splitContainer)) { return false; return false; } } Loading Loading @@ -1233,7 +1253,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Splits that are not showing side-by-side are reported as having 0 split // Splits that are not showing side-by-side are reported as having 0 split // ratio, since by definition in the API the primary container occupies no // ratio, since by definition in the API the primary container occupies no // width of the split when covered by the secondary. // width of the split when covered by the secondary. mPresenter.shouldShowSideBySide(container) shouldShowSideBySide(container) ? container.getSplitRule().getSplitRatio() ? container.getSplitRule().getSplitRatio() : 0.0f); : 0.0f); splitStates.add(splitState); splitStates.add(splitState); Loading Loading @@ -1402,7 +1422,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } // Decide whether the associated container should be retained based on the current // Decide whether the associated container should be retained based on the current // presentation mode. // presentation mode. if (mPresenter.shouldShowSideBySide(splitContainer)) { if (shouldShowSideBySide(splitContainer)) { return !shouldFinishAssociatedContainerWhenAdjacent(finishBehavior); return !shouldFinishAssociatedContainerWhenAdjacent(finishBehavior); } else { } else { return !shouldFinishAssociatedContainerWhenStacked(finishBehavior); return !shouldFinishAssociatedContainerWhenStacked(finishBehavior); Loading