Merge "Revert "Allow activity in ActivityEmbedding split to get Task windowing mode"" into tm-dev am: 4cac1be2ee
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18030738 Change-Id: I119f77343796b39c55a10a405865d3913c79461d Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
|
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -48,8 +49,7 @@ import java.util.concurrent.Executor;
|
|||||||
class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
||||||
|
|
||||||
/** Mapping from the client assigned unique token to the {@link TaskFragmentInfo}. */
|
/** Mapping from the client assigned unique token to the {@link TaskFragmentInfo}. */
|
||||||
@VisibleForTesting
|
private final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
|
||||||
final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping from the client assigned unique token to the TaskFragment parent
|
* Mapping from the client assigned unique token to the TaskFragment parent
|
||||||
@@ -120,29 +120,25 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param secondaryFragmentBounds the initial bounds for the secondary TaskFragment
|
* @param secondaryFragmentBounds the initial bounds for the secondary TaskFragment
|
||||||
* @param activityIntent Intent to start the secondary Activity with.
|
* @param activityIntent Intent to start the secondary Activity with.
|
||||||
* @param activityOptions ActivityOptions to start the secondary Activity with.
|
* @param activityOptions ActivityOptions to start the secondary Activity with.
|
||||||
* @param windowingMode the windowing mode to set for the TaskFragments.
|
|
||||||
*/
|
*/
|
||||||
void startActivityToSide(@NonNull WindowContainerTransaction wct,
|
void startActivityToSide(@NonNull WindowContainerTransaction wct,
|
||||||
@NonNull IBinder launchingFragmentToken, @NonNull Rect launchingFragmentBounds,
|
@NonNull IBinder launchingFragmentToken, @NonNull Rect launchingFragmentBounds,
|
||||||
@NonNull Activity launchingActivity, @NonNull IBinder secondaryFragmentToken,
|
@NonNull Activity launchingActivity, @NonNull IBinder secondaryFragmentToken,
|
||||||
@NonNull Rect secondaryFragmentBounds, @NonNull Intent activityIntent,
|
@NonNull Rect secondaryFragmentBounds, @NonNull Intent activityIntent,
|
||||||
@Nullable Bundle activityOptions, @NonNull SplitRule rule,
|
@Nullable Bundle activityOptions, @NonNull SplitRule rule) {
|
||||||
@WindowingMode int windowingMode) {
|
|
||||||
final IBinder ownerToken = launchingActivity.getActivityToken();
|
final IBinder ownerToken = launchingActivity.getActivityToken();
|
||||||
|
|
||||||
// Create or resize the launching TaskFragment.
|
// Create or resize the launching TaskFragment.
|
||||||
if (mFragmentInfos.containsKey(launchingFragmentToken)) {
|
if (mFragmentInfos.containsKey(launchingFragmentToken)) {
|
||||||
resizeTaskFragment(wct, launchingFragmentToken, launchingFragmentBounds);
|
resizeTaskFragment(wct, launchingFragmentToken, launchingFragmentBounds);
|
||||||
wct.setWindowingMode(mFragmentInfos.get(launchingFragmentToken).getToken(),
|
|
||||||
windowingMode);
|
|
||||||
} else {
|
} else {
|
||||||
createTaskFragmentAndReparentActivity(wct, launchingFragmentToken, ownerToken,
|
createTaskFragmentAndReparentActivity(wct, launchingFragmentToken, ownerToken,
|
||||||
launchingFragmentBounds, windowingMode, launchingActivity);
|
launchingFragmentBounds, WINDOWING_MODE_MULTI_WINDOW, launchingActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a TaskFragment for the secondary activity.
|
// Create a TaskFragment for the secondary activity.
|
||||||
createTaskFragmentAndStartActivity(wct, secondaryFragmentToken, ownerToken,
|
createTaskFragmentAndStartActivity(wct, secondaryFragmentToken, ownerToken,
|
||||||
secondaryFragmentBounds, windowingMode, activityIntent,
|
secondaryFragmentBounds, WINDOWING_MODE_MULTI_WINDOW, activityIntent,
|
||||||
activityOptions);
|
activityOptions);
|
||||||
|
|
||||||
// Set adjacent to each other so that the containers below will be invisible.
|
// Set adjacent to each other so that the containers below will be invisible.
|
||||||
@@ -157,7 +153,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
void expandTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
void expandTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
||||||
resizeTaskFragment(wct, fragmentToken, new Rect());
|
resizeTaskFragment(wct, fragmentToken, new Rect());
|
||||||
setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
|
setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
|
||||||
setWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,15 +255,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
wct.setBounds(mFragmentInfos.get(fragmentToken).getToken(), bounds);
|
wct.setBounds(mFragmentInfos.get(fragmentToken).getToken(), bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setWindowingMode(WindowContainerTransaction wct, IBinder fragmentToken,
|
|
||||||
@WindowingMode int windowingMode) {
|
|
||||||
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
|
|
||||||
}
|
|
||||||
wct.setWindowingMode(mFragmentInfos.get(fragmentToken).getToken(), windowingMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleteTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
void deleteTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
||||||
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|||||||
@@ -257,9 +257,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
if (taskContainer == null) {
|
if (taskContainer == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean wasInPip = taskContainer.isInPictureInPicture();
|
final boolean wasInPip = isInPictureInPicture(taskContainer.getConfiguration());
|
||||||
final boolean isInPIp = isInPictureInPicture(config);
|
final boolean isInPIp = isInPictureInPicture(config);
|
||||||
taskContainer.setWindowingMode(config.windowConfiguration.getWindowingMode());
|
taskContainer.setConfiguration(config);
|
||||||
|
|
||||||
// We need to check the animation override when enter/exit PIP or has bounds changed.
|
// We need to check the animation override when enter/exit PIP or has bounds changed.
|
||||||
boolean shouldUpdateAnimationOverride = wasInPip != isInPIp;
|
boolean shouldUpdateAnimationOverride = wasInPip != isInPIp;
|
||||||
@@ -278,9 +278,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* bounds is large enough for at least one split rule.
|
* bounds is large enough for at least one split rule.
|
||||||
*/
|
*/
|
||||||
private void updateAnimationOverride(@NonNull TaskContainer taskContainer) {
|
private void updateAnimationOverride(@NonNull TaskContainer taskContainer) {
|
||||||
if (!taskContainer.isTaskBoundsInitialized()
|
if (!taskContainer.isTaskBoundsInitialized()) {
|
||||||
|| !taskContainer.isWindowingModeInitialized()) {
|
// We don't know about the Task bounds yet.
|
||||||
// We don't know about the Task bounds/windowingMode yet.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +293,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
|
|
||||||
private boolean supportSplit(@NonNull TaskContainer taskContainer) {
|
private boolean supportSplit(@NonNull TaskContainer taskContainer) {
|
||||||
// No split inside PIP.
|
// No split inside PIP.
|
||||||
if (taskContainer.isInPictureInPicture()) {
|
if (isInPictureInPicture(taskContainer.getConfiguration())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check if the parent container bounds can support any split rule.
|
// Check if the parent container bounds can support any split rule.
|
||||||
@@ -462,12 +461,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
if (!taskContainer.setTaskBounds(taskBounds)) {
|
if (!taskContainer.setTaskBounds(taskBounds)) {
|
||||||
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
||||||
}
|
}
|
||||||
|
updateAnimationOverride(taskContainer);
|
||||||
}
|
}
|
||||||
if (!taskContainer.isWindowingModeInitialized()) {
|
|
||||||
taskContainer.setWindowingMode(activityInTask.getResources().getConfiguration()
|
|
||||||
.windowConfiguration.getWindowingMode());
|
|
||||||
}
|
|
||||||
updateAnimationOverride(taskContainer);
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
import android.app.WindowConfiguration.WindowingMode;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -112,16 +111,13 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
primaryActivity, primaryRectBounds, null);
|
primaryActivity, primaryRectBounds, null);
|
||||||
|
|
||||||
// Create new empty task fragment
|
// Create new empty task fragment
|
||||||
final int taskId = primaryContainer.getTaskId();
|
|
||||||
final TaskFragmentContainer secondaryContainer = mController.newContainer(
|
final TaskFragmentContainer secondaryContainer = mController.newContainer(
|
||||||
null /* activity */, primaryActivity, taskId);
|
null /* activity */, primaryActivity, primaryContainer.getTaskId());
|
||||||
final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds,
|
final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds,
|
||||||
rule, isLtr(primaryActivity, rule));
|
rule, isLtr(primaryActivity, rule));
|
||||||
final int windowingMode = mController.getTaskContainer(taskId)
|
|
||||||
.getWindowingModeForSplitTaskFragment(secondaryRectBounds);
|
|
||||||
createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(),
|
createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(),
|
||||||
primaryActivity.getActivityToken(), secondaryRectBounds,
|
primaryActivity.getActivityToken(), secondaryRectBounds,
|
||||||
windowingMode);
|
WINDOWING_MODE_MULTI_WINDOW);
|
||||||
secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
|
secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
|
||||||
|
|
||||||
// Set adjacent to each other so that the containers below will be invisible.
|
// Set adjacent to each other so that the containers below will be invisible.
|
||||||
@@ -177,7 +173,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
|
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
createTaskFragment(wct, newContainer.getTaskFragmentToken(),
|
createTaskFragment(wct, newContainer.getTaskFragmentToken(),
|
||||||
launchingActivity.getActivityToken(), new Rect(), WINDOWING_MODE_UNDEFINED);
|
launchingActivity.getActivityToken(), new Rect(), WINDOWING_MODE_MULTI_WINDOW);
|
||||||
|
|
||||||
applyTransaction(wct);
|
applyTransaction(wct);
|
||||||
return newContainer;
|
return newContainer;
|
||||||
@@ -193,17 +189,15 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
@NonNull Rect bounds, @Nullable TaskFragmentContainer containerToAvoid) {
|
@NonNull Rect bounds, @Nullable TaskFragmentContainer containerToAvoid) {
|
||||||
TaskFragmentContainer container = mController.getContainerWithActivity(
|
TaskFragmentContainer container = mController.getContainerWithActivity(
|
||||||
activity.getActivityToken());
|
activity.getActivityToken());
|
||||||
final int taskId = container != null ? container.getTaskId() : activity.getTaskId();
|
|
||||||
final int windowingMode = mController.getTaskContainer(taskId)
|
|
||||||
.getWindowingModeForSplitTaskFragment(bounds);
|
|
||||||
if (container == null || container == containerToAvoid) {
|
if (container == null || container == containerToAvoid) {
|
||||||
container = mController.newContainer(activity, taskId);
|
container = mController.newContainer(activity, activity.getTaskId());
|
||||||
|
|
||||||
final TaskFragmentCreationParams fragmentOptions =
|
final TaskFragmentCreationParams fragmentOptions =
|
||||||
createFragmentOptions(
|
createFragmentOptions(
|
||||||
container.getTaskFragmentToken(),
|
container.getTaskFragmentToken(),
|
||||||
activity.getActivityToken(),
|
activity.getActivityToken(),
|
||||||
bounds,
|
bounds,
|
||||||
windowingMode);
|
WINDOWING_MODE_MULTI_WINDOW);
|
||||||
wct.createTaskFragment(fragmentOptions);
|
wct.createTaskFragment(fragmentOptions);
|
||||||
|
|
||||||
wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
|
wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
|
||||||
@@ -212,7 +206,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
container.setLastRequestedBounds(bounds);
|
container.setLastRequestedBounds(bounds);
|
||||||
} else {
|
} else {
|
||||||
resizeTaskFragmentIfRegistered(wct, container, bounds);
|
resizeTaskFragmentIfRegistered(wct, container, bounds);
|
||||||
updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
@@ -244,17 +237,14 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
launchingActivity.getTaskId());
|
launchingActivity.getTaskId());
|
||||||
}
|
}
|
||||||
|
|
||||||
final int taskId = primaryContainer.getTaskId();
|
|
||||||
TaskFragmentContainer secondaryContainer = mController.newContainer(null /* activity */,
|
TaskFragmentContainer secondaryContainer = mController.newContainer(null /* activity */,
|
||||||
launchingActivity, taskId);
|
launchingActivity, primaryContainer.getTaskId());
|
||||||
final int windowingMode = mController.getTaskContainer(taskId)
|
|
||||||
.getWindowingModeForSplitTaskFragment(primaryRectBounds);
|
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer,
|
mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer,
|
||||||
rule);
|
rule);
|
||||||
startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
|
startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
|
||||||
launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
|
launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
|
||||||
activityIntent, activityOptions, rule, windowingMode);
|
activityIntent, activityOptions, rule);
|
||||||
if (isPlaceholder) {
|
if (isPlaceholder) {
|
||||||
// When placeholder is launched in split, we should keep the focus on the primary.
|
// When placeholder is launched in split, we should keep the focus on the primary.
|
||||||
wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
|
wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
|
||||||
@@ -302,12 +292,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
// When placeholder is shown in split, we should keep the focus on the primary.
|
// When placeholder is shown in split, we should keep the focus on the primary.
|
||||||
wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
|
wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
|
||||||
}
|
}
|
||||||
final TaskContainer taskContainer = mController.getTaskContainer(
|
|
||||||
updatedContainer.getTaskId());
|
|
||||||
final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment(
|
|
||||||
primaryRectBounds);
|
|
||||||
updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode);
|
|
||||||
updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
|
private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
|
||||||
@@ -339,15 +323,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds);
|
resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTaskFragmentWindowingModeIfRegistered(
|
|
||||||
@NonNull WindowContainerTransaction wct,
|
|
||||||
@NonNull TaskFragmentContainer container,
|
|
||||||
@WindowingMode int windowingMode) {
|
|
||||||
if (container.getInfo() != null) {
|
|
||||||
wct.setWindowingMode(container.getInfo().getToken(), windowingMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
|
void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
|
||||||
@Nullable Rect bounds) {
|
@Nullable Rect bounds) {
|
||||||
|
|||||||
@@ -16,14 +16,9 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.WindowConfiguration;
|
import android.content.res.Configuration;
|
||||||
import android.app.WindowConfiguration.WindowingMode;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -42,9 +37,9 @@ class TaskContainer {
|
|||||||
/** Available window bounds of this Task. */
|
/** Available window bounds of this Task. */
|
||||||
private final Rect mTaskBounds = new Rect();
|
private final Rect mTaskBounds = new Rect();
|
||||||
|
|
||||||
/** Windowing mode of this Task. */
|
/** Configuration of the Task. */
|
||||||
@WindowingMode
|
@Nullable
|
||||||
private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
|
private Configuration mConfiguration;
|
||||||
|
|
||||||
/** Active TaskFragments in this Task. */
|
/** Active TaskFragments in this Task. */
|
||||||
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
|
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
|
||||||
@@ -86,42 +81,13 @@ class TaskContainer {
|
|||||||
return !mTaskBounds.isEmpty();
|
return !mTaskBounds.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowingMode(int windowingMode) {
|
@Nullable
|
||||||
mWindowingMode = windowingMode;
|
Configuration getConfiguration() {
|
||||||
|
return mConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether the Task windowing mode has been initialized. */
|
void setConfiguration(@Nullable Configuration configuration) {
|
||||||
boolean isWindowingModeInitialized() {
|
mConfiguration = configuration;
|
||||||
return mWindowingMode != WINDOWING_MODE_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the windowing mode for the TaskFragments below this Task, which should be split with
|
|
||||||
* other TaskFragments.
|
|
||||||
*
|
|
||||||
* @param taskFragmentBounds Requested bounds for the TaskFragment. It will be empty when
|
|
||||||
* the pair of TaskFragments are stacked due to the limited space.
|
|
||||||
*/
|
|
||||||
@WindowingMode
|
|
||||||
int getWindowingModeForSplitTaskFragment(@Nullable Rect taskFragmentBounds) {
|
|
||||||
// Only set to multi-windowing mode if the pair are showing side-by-side. Otherwise, it
|
|
||||||
// will be set to UNDEFINED which will then inherit the Task windowing mode.
|
|
||||||
if (taskFragmentBounds == null || taskFragmentBounds.isEmpty()) {
|
|
||||||
return WINDOWING_MODE_UNDEFINED;
|
|
||||||
}
|
|
||||||
// We use WINDOWING_MODE_MULTI_WINDOW when the Task is fullscreen.
|
|
||||||
// However, when the Task is in other multi windowing mode, such as Freeform, we need to
|
|
||||||
// have the activity windowing mode to match the Task, otherwise things like
|
|
||||||
// DecorCaptionView won't work correctly. As a result, have the TaskFragment to be in the
|
|
||||||
// Task windowing mode if the Task is in multi window.
|
|
||||||
// TODO we won't need this anymore after we migrate Freeform caption to WM Shell.
|
|
||||||
return WindowConfiguration.inMultiWindowMode(mWindowingMode)
|
|
||||||
? mWindowingMode
|
|
||||||
: WINDOWING_MODE_MULTI_WINDOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isInPictureInPicture() {
|
|
||||||
return mWindowingMode == WINDOWING_MODE_PINNED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether there is any {@link TaskFragmentContainer} below this Task. */
|
/** Whether there is any {@link TaskFragmentContainer} below this Task. */
|
||||||
|
|||||||
@@ -16,23 +16,15 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
|
||||||
|
|
||||||
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 org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.window.TaskFragmentInfo;
|
|
||||||
import android.window.WindowContainerToken;
|
|
||||||
import android.window.WindowContainerTransaction;
|
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
@@ -43,8 +35,6 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for {@link JetpackTaskFragmentOrganizer}.
|
* Test class for {@link JetpackTaskFragmentOrganizer}.
|
||||||
*
|
*
|
||||||
@@ -57,8 +47,6 @@ import java.util.ArrayList;
|
|||||||
public class JetpackTaskFragmentOrganizerTest {
|
public class JetpackTaskFragmentOrganizerTest {
|
||||||
private static final int TASK_ID = 10;
|
private static final int TASK_ID = 10;
|
||||||
|
|
||||||
@Mock
|
|
||||||
private WindowContainerTransaction mTransaction;
|
|
||||||
@Mock
|
@Mock
|
||||||
private JetpackTaskFragmentOrganizer.TaskFragmentCallback mCallback;
|
private JetpackTaskFragmentOrganizer.TaskFragmentCallback mCallback;
|
||||||
private JetpackTaskFragmentOrganizer mOrganizer;
|
private JetpackTaskFragmentOrganizer mOrganizer;
|
||||||
@@ -103,24 +91,4 @@ public class JetpackTaskFragmentOrganizerTest {
|
|||||||
|
|
||||||
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
|
verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpandTaskFragment() {
|
|
||||||
final TaskFragmentContainer container = new TaskFragmentContainer(null, TASK_ID);
|
|
||||||
final TaskFragmentInfo info = createMockInfo(container);
|
|
||||||
mOrganizer.mFragmentInfos.put(container.getTaskFragmentToken(), info);
|
|
||||||
container.setInfo(info);
|
|
||||||
|
|
||||||
mOrganizer.expandTaskFragment(mTransaction, container.getTaskFragmentToken());
|
|
||||||
|
|
||||||
verify(mTransaction).setWindowingMode(container.getInfo().getToken(),
|
|
||||||
WINDOWING_MODE_UNDEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TaskFragmentInfo createMockInfo(TaskFragmentContainer container) {
|
|
||||||
return new TaskFragmentInfo(container.getTaskFragmentToken(),
|
|
||||||
mock(WindowContainerToken.class), new Configuration(), 0 /* runningActivityCount */,
|
|
||||||
false /* isVisible */, new ArrayList<>(), new Point(),
|
|
||||||
false /* isTaskClearedForReuse */, false /* isTaskFragmentClearedForPip */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,6 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@@ -70,56 +63,6 @@ public class TaskContainerTest {
|
|||||||
assertFalse(taskContainer.setTaskBounds(TASK_BOUNDS));
|
assertFalse(taskContainer.setTaskBounds(TASK_BOUNDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsWindowingModeInitialized() {
|
|
||||||
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
|
|
||||||
|
|
||||||
assertFalse(taskContainer.isWindowingModeInitialized());
|
|
||||||
|
|
||||||
taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
|
|
||||||
|
|
||||||
assertTrue(taskContainer.isWindowingModeInitialized());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetWindowingModeForSplitTaskFragment() {
|
|
||||||
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
|
|
||||||
final Rect splitBounds = new Rect(0, 0, 500, 1000);
|
|
||||||
|
|
||||||
assertEquals(WINDOWING_MODE_MULTI_WINDOW,
|
|
||||||
taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
|
|
||||||
|
|
||||||
taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
|
|
||||||
|
|
||||||
assertEquals(WINDOWING_MODE_MULTI_WINDOW,
|
|
||||||
taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
|
|
||||||
|
|
||||||
taskContainer.setWindowingMode(WINDOWING_MODE_FREEFORM);
|
|
||||||
|
|
||||||
assertEquals(WINDOWING_MODE_FREEFORM,
|
|
||||||
taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
|
|
||||||
|
|
||||||
// Empty bounds means the split pair are stacked, so it should be UNDEFINED which will then
|
|
||||||
// inherit the Task windowing mode
|
|
||||||
assertEquals(WINDOWING_MODE_UNDEFINED,
|
|
||||||
taskContainer.getWindowingModeForSplitTaskFragment(new Rect()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsInPictureInPicture() {
|
|
||||||
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
|
|
||||||
|
|
||||||
assertFalse(taskContainer.isInPictureInPicture());
|
|
||||||
|
|
||||||
taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
|
|
||||||
|
|
||||||
assertFalse(taskContainer.isInPictureInPicture());
|
|
||||||
|
|
||||||
taskContainer.setWindowingMode(WINDOWING_MODE_PINNED);
|
|
||||||
|
|
||||||
assertTrue(taskContainer.isInPictureInPicture());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsEmpty() {
|
public void testIsEmpty() {
|
||||||
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
|
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
|
||||||
|
|||||||
Reference in New Issue
Block a user