Merge "Consolidate mTaskBounds logic to mConfiguration" into tm-qpr-dev am: 85a7c3a90b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20071569 Change-Id: I73108304ecc1e97784e03e105dc2fddee8d13c40 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -227,12 +227,13 @@ public class ActivityClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
|
* Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
|
||||||
* found.
|
* the task {@link Configuration} cannot be obtained.
|
||||||
*/
|
*/
|
||||||
public int getTaskWindowingMode(IBinder activityToken) {
|
@Nullable
|
||||||
|
public Configuration getTaskConfiguration(IBinder activityToken) {
|
||||||
try {
|
try {
|
||||||
return getActivityClientController().getTaskWindowingMode(activityToken);
|
return getActivityClientController().getTaskConfiguration(activityToken);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,11 @@ interface IActivityClientController {
|
|||||||
boolean willActivityBeVisible(in IBinder token);
|
boolean willActivityBeVisible(in IBinder token);
|
||||||
int getDisplayId(in IBinder activityToken);
|
int getDisplayId(in IBinder activityToken);
|
||||||
int getTaskForActivity(in IBinder token, in boolean onlyRoot);
|
int getTaskForActivity(in IBinder token, in boolean onlyRoot);
|
||||||
int getTaskWindowingMode(in IBinder activityToken);
|
/**
|
||||||
|
* Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
|
||||||
|
* the task {@link Configuration} cannot be obtained.
|
||||||
|
*/
|
||||||
|
Configuration getTaskConfiguration(in IBinder activityToken);
|
||||||
IBinder getActivityTokenBelow(IBinder token);
|
IBinder getActivityTokenBelow(IBinder token);
|
||||||
ComponentName getCallingActivity(in IBinder token);
|
ComponentName getCallingActivity(in IBinder token);
|
||||||
String getCallingPackage(in IBinder token);
|
String getCallingPackage(in IBinder token);
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAs
|
|||||||
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
|
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
|
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
|
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds;
|
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit;
|
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -464,7 +463,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
// parentInfo#isVisibleRequested is true.
|
// parentInfo#isVisibleRequested is true.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onTaskContainerInfoChanged(taskContainer, parentInfo.getConfiguration());
|
|
||||||
if (isInPictureInPicture(parentInfo.getConfiguration())) {
|
if (isInPictureInPicture(parentInfo.getConfiguration())) {
|
||||||
// No need to update presentation in PIP until the Task exit PIP.
|
// No need to update presentation in PIP until the Task exit PIP.
|
||||||
return;
|
return;
|
||||||
@@ -614,12 +612,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer,
|
|
||||||
@NonNull Configuration config) {
|
|
||||||
taskContainer.setTaskBounds(config.windowConfiguration.getBounds());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether the given {@link TaskContainer} may show in split. */
|
/** Returns whether the given {@link TaskContainer} may show in split. */
|
||||||
// Suppress GuardedBy warning because lint asks to mark this method as
|
// Suppress GuardedBy warning because lint asks to mark this method as
|
||||||
// @GuardedBy(mPresenter.mController.mLock), which is mLock itself
|
// @GuardedBy(mPresenter.mController.mLock), which is mLock itself
|
||||||
@@ -1235,13 +1227,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
final TaskContainer taskContainer = mTaskContainers.get(taskId);
|
final TaskContainer taskContainer = mTaskContainers.get(taskId);
|
||||||
final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity,
|
final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity,
|
||||||
pendingAppearedIntent, taskContainer, this);
|
pendingAppearedIntent, taskContainer, this);
|
||||||
if (!taskContainer.isTaskBoundsInitialized()) {
|
|
||||||
// Get the initial bounds before the TaskFragment has appeared.
|
|
||||||
final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask);
|
|
||||||
if (!taskContainer.setTaskBounds(taskBounds)) {
|
|
||||||
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -932,11 +932,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
if (taskContainer != null) {
|
if (taskContainer != null) {
|
||||||
return taskContainer.getTaskProperties();
|
return taskContainer.getTaskProperties();
|
||||||
}
|
}
|
||||||
// Use a copy of configuration because activity's configuration may be updated later,
|
return TaskProperties.getTaskPropertiesFromActivity(activity);
|
||||||
// or we may get unexpected TaskContainer's configuration if Activity's configuration is
|
|
||||||
// updated. An example is Activity is going to be in split.
|
|
||||||
return new TaskProperties(activity.getDisplayId(),
|
|
||||||
new Configuration(activity.getResources().getConfiguration()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -950,16 +946,4 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
// TODO(b/190433398): Supply correct insets.
|
// TODO(b/190433398): Supply correct insets.
|
||||||
return new WindowMetrics(taskBounds, WindowInsets.CONSUMED);
|
return new WindowMetrics(taskBounds, WindowInsets.CONSUMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Obtains the bounds from a non-embedded Activity. */
|
|
||||||
@NonNull
|
|
||||||
static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) {
|
|
||||||
final WindowConfiguration windowConfiguration =
|
|
||||||
activity.getResources().getConfiguration().windowConfiguration;
|
|
||||||
if (!activity.isInMultiWindowMode()) {
|
|
||||||
// In fullscreen mode the max bounds should correspond to the task bounds.
|
|
||||||
return windowConfiguration.getMaxBounds();
|
|
||||||
}
|
|
||||||
return windowConfiguration.getBounds();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,17 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
|
import static android.app.WindowConfiguration.inMultiWindowMode;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityClient;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
import android.app.WindowConfiguration.WindowingMode;
|
import android.app.WindowConfiguration.WindowingMode;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.Log;
|
||||||
import android.window.TaskFragmentInfo;
|
import android.window.TaskFragmentInfo;
|
||||||
import android.window.TaskFragmentParentInfo;
|
import android.window.TaskFragmentParentInfo;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
@@ -41,14 +44,11 @@ import java.util.Set;
|
|||||||
|
|
||||||
/** Represents TaskFragments and split pairs below a Task. */
|
/** Represents TaskFragments and split pairs below a Task. */
|
||||||
class TaskContainer {
|
class TaskContainer {
|
||||||
|
private static final String TAG = TaskContainer.class.getSimpleName();
|
||||||
|
|
||||||
/** The unique task id. */
|
/** The unique task id. */
|
||||||
private final int mTaskId;
|
private final int mTaskId;
|
||||||
|
|
||||||
// TODO(b/240219484): consolidate to mConfiguration
|
|
||||||
/** Available window bounds of this Task. */
|
|
||||||
private final Rect mTaskBounds = new Rect();
|
|
||||||
|
|
||||||
/** Active TaskFragments in this Task. */
|
/** Active TaskFragments in this Task. */
|
||||||
@NonNull
|
@NonNull
|
||||||
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
|
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
|
||||||
@@ -86,10 +86,10 @@ class TaskContainer {
|
|||||||
throw new IllegalArgumentException("Invalid Task id");
|
throw new IllegalArgumentException("Invalid Task id");
|
||||||
}
|
}
|
||||||
mTaskId = taskId;
|
mTaskId = taskId;
|
||||||
// Make a copy in case the activity's config is updated, and updates the TaskContainer's
|
final TaskProperties taskProperties = TaskProperties
|
||||||
// config unexpectedly.
|
.getTaskPropertiesFromActivity(activityInTask);
|
||||||
mConfiguration = new Configuration(activityInTask.getResources().getConfiguration());
|
mConfiguration = taskProperties.getConfiguration();
|
||||||
mDisplayId = activityInTask.getDisplayId();
|
mDisplayId = taskProperties.getDisplayId();
|
||||||
// Note that it is always called when there's a new Activity is started, which implies
|
// Note that it is always called when there's a new Activity is started, which implies
|
||||||
// the host task is visible.
|
// the host task is visible.
|
||||||
mIsVisible = true;
|
mIsVisible = true;
|
||||||
@@ -107,25 +107,6 @@ class TaskContainer {
|
|||||||
return mIsVisible;
|
return mIsVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
Rect getTaskBounds() {
|
|
||||||
return mTaskBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns {@code true} if the bounds is changed. */
|
|
||||||
boolean setTaskBounds(@NonNull Rect taskBounds) {
|
|
||||||
if (!taskBounds.isEmpty() && !mTaskBounds.equals(taskBounds)) {
|
|
||||||
mTaskBounds.set(taskBounds);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Whether the Task bounds has been initialized. */
|
|
||||||
boolean isTaskBoundsInitialized() {
|
|
||||||
return !mTaskBounds.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Configuration getConfiguration() {
|
Configuration getConfiguration() {
|
||||||
// Make a copy in case the config is updated unexpectedly.
|
// Make a copy in case the config is updated unexpectedly.
|
||||||
@@ -261,5 +242,45 @@ class TaskContainer {
|
|||||||
Configuration getConfiguration() {
|
Configuration getConfiguration() {
|
||||||
return mConfiguration;
|
return mConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the {@link TaskProperties} for the task that the provided {@link Activity} is
|
||||||
|
* associated with.
|
||||||
|
* <p>
|
||||||
|
* Note that for most case, caller should use
|
||||||
|
* {@link SplitPresenter#getTaskProperties(Activity)} instead. This method is used before
|
||||||
|
* the {@code activity} goes into split.
|
||||||
|
* </p><p>
|
||||||
|
* If the {@link Activity} is in fullscreen, override
|
||||||
|
* {@link WindowConfiguration#getBounds()} with {@link WindowConfiguration#getMaxBounds()}
|
||||||
|
* in case the {@link Activity} is letterboxed. Otherwise, get the Task
|
||||||
|
* {@link Configuration} from the server side or use {@link Activity}'s
|
||||||
|
* {@link Configuration} as a fallback if the Task {@link Configuration} cannot be obtained.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
static TaskProperties getTaskPropertiesFromActivity(@NonNull Activity activity) {
|
||||||
|
final int displayId = activity.getDisplayId();
|
||||||
|
// Use a copy of configuration because activity's configuration may be updated later,
|
||||||
|
// or we may get unexpected TaskContainer's configuration if Activity's configuration is
|
||||||
|
// updated. An example is Activity is going to be in split.
|
||||||
|
final Configuration activityConfig = new Configuration(
|
||||||
|
activity.getResources().getConfiguration());
|
||||||
|
final WindowConfiguration windowConfiguration = activityConfig.windowConfiguration;
|
||||||
|
final int windowingMode = windowConfiguration.getWindowingMode();
|
||||||
|
if (!inMultiWindowMode(windowingMode)) {
|
||||||
|
// Use the max bounds in fullscreen in case the Activity is letterboxed.
|
||||||
|
windowConfiguration.setBounds(windowConfiguration.getMaxBounds());
|
||||||
|
return new TaskProperties(displayId, activityConfig);
|
||||||
|
}
|
||||||
|
final Configuration taskConfig = ActivityClient.getInstance()
|
||||||
|
.getTaskConfiguration(activity.getActivityToken());
|
||||||
|
if (taskConfig == null) {
|
||||||
|
Log.w(TAG, "Could not obtain task configuration for activity:" + activity);
|
||||||
|
// Still report activity config if task config cannot be obtained from the server
|
||||||
|
// side.
|
||||||
|
return new TaskProperties(displayId, activityConfig);
|
||||||
|
}
|
||||||
|
return new TaskProperties(displayId, taskConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import android.graphics.Rect;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.window.WindowContext;
|
|
||||||
import android.window.WindowProvider;
|
import android.window.WindowProvider;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -310,20 +309,21 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
|||||||
}
|
}
|
||||||
final int windowingMode;
|
final int windowingMode;
|
||||||
if (context instanceof Activity) {
|
if (context instanceof Activity) {
|
||||||
windowingMode = ActivityClient.getInstance().getTaskWindowingMode(
|
final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration(
|
||||||
context.getActivityToken());
|
context.getActivityToken());
|
||||||
|
if (taskConfig == null) {
|
||||||
|
// If we cannot determine the task configuration for any reason, it is likely that
|
||||||
|
// we won't be able to determine its position correctly as well. DisplayFeatures'
|
||||||
|
// bounds in this case can't be computed correctly, so we should skip.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
windowingMode = taskConfig.windowConfiguration.getWindowingMode();
|
||||||
} else {
|
} else {
|
||||||
// TODO(b/242674941): use task windowing mode for window context that associates with
|
// TODO(b/242674941): use task windowing mode for window context that associates with
|
||||||
// activity.
|
// activity.
|
||||||
windowingMode = context.getResources().getConfiguration().windowConfiguration
|
windowingMode = context.getResources().getConfiguration().windowConfiguration
|
||||||
.getWindowingMode();
|
.getWindowingMode();
|
||||||
}
|
}
|
||||||
if (windowingMode == -1) {
|
|
||||||
// If we cannot determine the task windowing mode for any reason, it is likely that we
|
|
||||||
// won't be able to determine its position correctly as well. DisplayFeatures' bounds
|
|
||||||
// in this case can't be computed correctly, so we should skip.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// It is recommended not to report any display features in multi-window mode, since it
|
// It is recommended not to report any display features in multi-window mode, since it
|
||||||
// won't be possible to synchronize the display feature positions with window movement.
|
// won't be possible to synchronize the display feature positions with window movement.
|
||||||
return !WindowConfiguration.inMultiWindowMode(windowingMode);
|
return !WindowConfiguration.inMultiWindowMode(windowingMode);
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ public class SplitControllerTest {
|
|||||||
|
|
||||||
assertNotNull(tf);
|
assertNotNull(tf);
|
||||||
assertNotNull(taskContainer);
|
assertNotNull(taskContainer);
|
||||||
assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds());
|
assertEquals(TASK_BOUNDS, taskContainer.getConfiguration().windowConfiguration.getBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
|
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
|
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -67,28 +66,6 @@ public class TaskContainerTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsTaskBoundsInitialized() {
|
|
||||||
final TaskContainer taskContainer = createTestTaskContainer();
|
|
||||||
|
|
||||||
assertFalse(taskContainer.isTaskBoundsInitialized());
|
|
||||||
|
|
||||||
taskContainer.setTaskBounds(TASK_BOUNDS);
|
|
||||||
|
|
||||||
assertTrue(taskContainer.isTaskBoundsInitialized());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetTaskBounds() {
|
|
||||||
final TaskContainer taskContainer = createTestTaskContainer();
|
|
||||||
|
|
||||||
assertFalse(taskContainer.setTaskBounds(new Rect()));
|
|
||||||
|
|
||||||
assertTrue(taskContainer.setTaskBounds(TASK_BOUNDS));
|
|
||||||
|
|
||||||
assertFalse(taskContainer.setTaskBounds(TASK_BOUNDS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetWindowingModeForSplitTaskFragment() {
|
public void testGetWindowingModeForSplitTaskFragment() {
|
||||||
final TaskContainer taskContainer = createTestTaskContainer();
|
final TaskContainer taskContainer = createTestTaskContainer();
|
||||||
|
|||||||
@@ -580,17 +580,18 @@ class ActivityClientController extends IActivityClientController.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
|
* Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
|
||||||
* found.
|
* the task {@link Configuration} cannot be obtained.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getTaskWindowingMode(IBinder activityToken) {
|
@Nullable
|
||||||
|
public Configuration getTaskConfiguration(IBinder activityToken) {
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken);
|
final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken);
|
||||||
if (ar == null) {
|
if (ar == null) {
|
||||||
return -1;
|
return null;
|
||||||
}
|
}
|
||||||
return ar.getTask().getWindowingMode();
|
return ar.getTask().getConfiguration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user