Merge "Merge "Skip duplicate setBounds requests for task fragments" into sc-v2-dev am: 7d1040f716" into sc-v2-dev-plus-aosp
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java
index 7298d34..6f67881 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitController.java
@@ -99,39 +99,38 @@
 
     @Override
     public void onTaskFragmentAppeared(@NonNull TaskFragmentAppearedInfo taskFragmentAppearedInfo) {
-        for (TaskFragmentContainer container : mContainers) {
-            if (container.getTaskFragmentToken().equals(
-                    taskFragmentAppearedInfo.getTaskFragmentInfo().getFragmentToken())) {
-                container.setInfo(taskFragmentAppearedInfo.getTaskFragmentInfo());
-                return;
-            }
+        TaskFragmentContainer container = getContainer(
+                taskFragmentAppearedInfo.getTaskFragmentInfo().getFragmentToken());
+        if (container == null) {
+            return;
         }
+
+        container.setInfo(taskFragmentAppearedInfo.getTaskFragmentInfo());
     }
 
     @Override
     public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {
-        for (TaskFragmentContainer container : mContainers) {
-            if (container.getTaskFragmentToken().equals(taskFragmentInfo.getFragmentToken())) {
-                container.setInfo(taskFragmentInfo);
+        TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
+        if (container == null) {
+            return;
+        }
 
-                if (taskFragmentInfo.isEmpty()) {
-                    cleanupContainer(container, true /* shouldFinishDependent */);
-                    updateCallbackIfNecessary();
-                }
-                return;
-            }
+        container.setInfo(taskFragmentInfo);
+        if (taskFragmentInfo.isEmpty()) {
+            cleanupContainer(container, true /* shouldFinishDependent */);
+            updateCallbackIfNecessary();
         }
     }
 
     @Override
     public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {
-        for (TaskFragmentContainer container : mContainers) {
-            if (container.getTaskFragmentToken().equals(taskFragmentInfo.getFragmentToken())) {
-                cleanupContainer(container, true /* shouldFinishDependent */);
-                updateCallbackIfNecessary();
-                return;
-            }
+        TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
+        if (container == null) {
+            return;
         }
+
+        cleanupContainer(container, true /* shouldFinishDependent */);
+        updateCallbackIfNecessary();
     }
 
     @Override
@@ -480,7 +479,7 @@
     }
 
     @Nullable
-    private TaskFragmentContainer getContainer(@NonNull IBinder fragmentToken) {
+    TaskFragmentContainer getContainer(@NonNull IBinder fragmentToken) {
         for (TaskFragmentContainer container : mContainers) {
             if (container.getTaskFragmentToken().equals(fragmentToken)) {
                 return container;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitPresenter.java
index 381d6d7..90af72b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/SplitPresenter.java
@@ -23,6 +23,7 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.window.TaskFragmentCreationParams;
 import android.window.WindowContainerTransaction;
 
@@ -98,8 +99,6 @@
 
         final Rect parentBounds = getParentContainerBounds(primaryActivity);
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_LEFT, parentBounds, rule);
-        final Rect secondaryRectBounds = getBoundsForPosition(POSITION_RIGHT, parentBounds, rule);
-
         TaskFragmentContainer primaryContainer = mController.getContainerWithActivity(
                 primaryActivity.getActivityToken());
         if (primaryContainer == null) {
@@ -115,10 +114,13 @@
 
             wct.reparentActivityToTaskFragment(primaryContainer.getTaskFragmentToken(),
                     primaryActivity.getActivityToken());
+
+            primaryContainer.setLastRequestedBounds(primaryRectBounds);
         } else {
             resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRectBounds);
         }
 
+        final Rect secondaryRectBounds = getBoundsForPosition(POSITION_RIGHT, parentBounds, rule);
         TaskFragmentContainer secondaryContainer = mController.getContainerWithActivity(
                 secondaryActivity.getActivityToken());
         if (secondaryContainer == null || secondaryContainer == primaryContainer) {
@@ -134,6 +136,8 @@
 
             wct.reparentActivityToTaskFragment(secondaryContainer.getTaskFragmentToken(),
                     secondaryActivity.getActivityToken());
+
+            secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
         } else {
             resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds);
         }
@@ -177,6 +181,9 @@
                 activityIntent,
                 activityOptions);
 
+        primaryContainer.setLastRequestedBounds(primaryRectBounds);
+        secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
+
         // TODO(b/190433398): The primary container and the secondary container should also be set
         // as adjacent (WCT#setAdjacentRoots) to make activities behind invisible.
 
@@ -199,7 +206,6 @@
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_LEFT, parentBounds, rule);
         final Rect secondaryRectBounds = getBoundsForPosition(POSITION_RIGHT, parentBounds, rule);
 
-        // TODO(b/190433398): Check if the bounds actually changed.
         // If the task fragments are not registered yet, the positions will be updated after they
         // are created again.
         resizeTaskFragmentIfRegistered(wct, splitContainer.getPrimaryContainer(),
@@ -219,10 +225,27 @@
         if (container.getInfo() == null) {
             return;
         }
-        // TODO(b/190433398): Check if the bounds actually changed.
         resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds);
     }
 
+    @Override
+    void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
+            @Nullable Rect bounds) {
+        TaskFragmentContainer container = mController.getContainer(fragmentToken);
+        if (container == null) {
+            throw new IllegalStateException(
+                    "Resizing a task fragment that is not registered with controller.");
+        }
+
+        if (container.areLastRequestedBoundsEqual(bounds)) {
+            // Return early if the provided bounds were already requested
+            return;
+        }
+
+        container.setLastRequestedBounds(bounds);
+        super.resizeTaskFragment(wct, fragmentToken, bounds);
+    }
+
     boolean shouldShowSideBySide(@NonNull SplitContainer splitContainer) {
         final Rect parentBounds = getParentContainerBounds(splitContainer.getPrimaryContainer());
         return shouldShowSideBySide(parentBounds, splitContainer.getSplitPairRule());
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java
index 3cf37a6..368adef 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/TaskFragmentContainer.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityThread;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
 import android.window.TaskFragmentInfo;
@@ -60,6 +61,11 @@
     private boolean mIsFinished;
 
     /**
+     * Bounds that were requested last via {@link android.window.WindowContainerTransaction}.
+     */
+    private final Rect mLastRequestedBounds = new Rect();
+
+    /**
      * Creates a container with an existing activity that will be re-parented to it in a window
      * container transaction.
      */
@@ -199,4 +205,23 @@
     boolean isFinished() {
         return mIsFinished;
     }
+
+    /**
+     * Checks if last requested bounds are equal to the provided value.
+     */
+    boolean areLastRequestedBoundsEqual(@Nullable Rect bounds) {
+        return (bounds == null && mLastRequestedBounds.isEmpty())
+                || mLastRequestedBounds.equals(bounds);
+    }
+
+    /**
+     * Updates the last requested bounds.
+     */
+    void setLastRequestedBounds(@Nullable Rect bounds) {
+        if (bounds == null) {
+            mLastRequestedBounds.setEmpty();
+        } else {
+            mLastRequestedBounds.set(bounds);
+        }
+    }
 }