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
|
||||
* found.
|
||||
* Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
|
||||
* the task {@link Configuration} cannot be obtained.
|
||||
*/
|
||||
public int getTaskWindowingMode(IBinder activityToken) {
|
||||
@Nullable
|
||||
public Configuration getTaskConfiguration(IBinder activityToken) {
|
||||
try {
|
||||
return getActivityClientController().getTaskWindowingMode(activityToken);
|
||||
return getActivityClientController().getTaskConfiguration(activityToken);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,11 @@ interface IActivityClientController {
|
||||
boolean willActivityBeVisible(in IBinder token);
|
||||
int getDisplayId(in IBinder activityToken);
|
||||
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);
|
||||
ComponentName getCallingActivity(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.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
|
||||
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 android.app.Activity;
|
||||
@@ -464,7 +463,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
// parentInfo#isVisibleRequested is true.
|
||||
return;
|
||||
}
|
||||
onTaskContainerInfoChanged(taskContainer, parentInfo.getConfiguration());
|
||||
if (isInPictureInPicture(parentInfo.getConfiguration())) {
|
||||
// No need to update presentation in PIP until the Task exit PIP.
|
||||
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. */
|
||||
// Suppress GuardedBy warning because lint asks to mark this method as
|
||||
// @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 TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -932,11 +932,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
if (taskContainer != null) {
|
||||
return taskContainer.getTaskProperties();
|
||||
}
|
||||
// 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.
|
||||
return new TaskProperties(activity.getDisplayId(),
|
||||
new Configuration(activity.getResources().getConfiguration()));
|
||||
return TaskProperties.getTaskPropertiesFromActivity(activity);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -950,16 +946,4 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
// TODO(b/190433398): Supply correct insets.
|
||||
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_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.inMultiWindowMode;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityClient;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.app.WindowConfiguration.WindowingMode;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.window.TaskFragmentInfo;
|
||||
import android.window.TaskFragmentParentInfo;
|
||||
import android.window.WindowContainerTransaction;
|
||||
@@ -41,14 +44,11 @@ import java.util.Set;
|
||||
|
||||
/** Represents TaskFragments and split pairs below a Task. */
|
||||
class TaskContainer {
|
||||
private static final String TAG = TaskContainer.class.getSimpleName();
|
||||
|
||||
/** The unique task id. */
|
||||
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. */
|
||||
@NonNull
|
||||
final List<TaskFragmentContainer> mContainers = new ArrayList<>();
|
||||
@@ -86,10 +86,10 @@ class TaskContainer {
|
||||
throw new IllegalArgumentException("Invalid Task id");
|
||||
}
|
||||
mTaskId = taskId;
|
||||
// Make a copy in case the activity's config is updated, and updates the TaskContainer's
|
||||
// config unexpectedly.
|
||||
mConfiguration = new Configuration(activityInTask.getResources().getConfiguration());
|
||||
mDisplayId = activityInTask.getDisplayId();
|
||||
final TaskProperties taskProperties = TaskProperties
|
||||
.getTaskPropertiesFromActivity(activityInTask);
|
||||
mConfiguration = taskProperties.getConfiguration();
|
||||
mDisplayId = taskProperties.getDisplayId();
|
||||
// Note that it is always called when there's a new Activity is started, which implies
|
||||
// the host task is visible.
|
||||
mIsVisible = true;
|
||||
@@ -107,25 +107,6 @@ class TaskContainer {
|
||||
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
|
||||
Configuration getConfiguration() {
|
||||
// Make a copy in case the config is updated unexpectedly.
|
||||
@@ -261,5 +242,45 @@ class TaskContainer {
|
||||
Configuration getConfiguration() {
|
||||
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.IBinder;
|
||||
import android.util.ArrayMap;
|
||||
import android.window.WindowContext;
|
||||
import android.window.WindowProvider;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -310,20 +309,21 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
}
|
||||
final int windowingMode;
|
||||
if (context instanceof Activity) {
|
||||
windowingMode = ActivityClient.getInstance().getTaskWindowingMode(
|
||||
final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration(
|
||||
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 {
|
||||
// TODO(b/242674941): use task windowing mode for window context that associates with
|
||||
// activity.
|
||||
windowingMode = context.getResources().getConfiguration().windowConfiguration
|
||||
.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
|
||||
// won't be possible to synchronize the display feature positions with window movement.
|
||||
return !WindowConfiguration.inMultiWindowMode(windowingMode);
|
||||
|
||||
@@ -261,7 +261,7 @@ public class SplitControllerTest {
|
||||
|
||||
assertNotNull(tf);
|
||||
assertNotNull(taskContainer);
|
||||
assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds());
|
||||
assertEquals(TASK_BOUNDS, taskContainer.getConfiguration().windowConfiguration.getBounds());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
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 org.junit.Assert.assertEquals;
|
||||
@@ -67,28 +66,6 @@ public class TaskContainerTest {
|
||||
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
|
||||
public void testGetWindowingModeForSplitTaskFragment() {
|
||||
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
|
||||
* found.
|
||||
* Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
|
||||
* the task {@link Configuration} cannot be obtained.
|
||||
*/
|
||||
@Override
|
||||
public int getTaskWindowingMode(IBinder activityToken) {
|
||||
@Nullable
|
||||
public Configuration getTaskConfiguration(IBinder activityToken) {
|
||||
synchronized (mGlobalLock) {
|
||||
final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken);
|
||||
if (ar == null) {
|
||||
return -1;
|
||||
return null;
|
||||
}
|
||||
return ar.getTask().getWindowingMode();
|
||||
return ar.getTask().getConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user