diff options
| author | 2023-02-09 16:16:44 +0000 | |
|---|---|---|
| committer | 2023-02-09 16:16:44 +0000 | |
| commit | d88325489e7f6e844d6961c6e4719c848d40e6d2 (patch) | |
| tree | eeaa9848294f603e2a957333b5537d594e355009 | |
| parent | d0376c0a7565a9064b4f00705cec180692cb27f5 (diff) | |
| parent | b3ec2ce0ef4606c8b62dc79bfbc2142c54bc1644 (diff) | |
Merge "Fix translucent activities when unfolding" into tm-qpr-dev am: b3ec2ce0ef
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21150127
Change-Id: I6a363828d5acb805b15b27b6f7e05c46aea01950
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
3 files changed, 75 insertions, 5 deletions
| diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 056b144a90b9..8aca912999cc 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8293,7 +8293,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A      }      void recomputeConfiguration() { -        onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); +        // We check if the current activity is transparent. In that case we need to +        // recomputeConfiguration of the first opaque activity beneath, to allow a +        // proper computation of the new bounds. +        if (!mLetterboxUiController.applyOnOpaqueActivityBelow( +                ActivityRecord::recomputeConfiguration)) { +            onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); +        }      }      boolean isInTransition() { diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 1aa0ec3c1280..d2e8ad1f66b9 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -81,6 +81,7 @@ import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTy  import static java.lang.Boolean.FALSE;  import static java.lang.Boolean.TRUE; +import android.annotation.NonNull;  import android.annotation.Nullable;  import android.app.ActivityManager.TaskDescription;  import android.content.pm.ActivityInfo.ScreenOrientation; @@ -104,7 +105,9 @@ import com.android.internal.statusbar.LetterboxDetails;  import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;  import java.io.PrintWriter; +import java.util.Optional;  import java.util.function.BooleanSupplier; +import java.util.function.Consumer;  import java.util.function.Predicate;  /** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */ @@ -1471,6 +1474,32 @@ final class LetterboxUiController {          return mInheritedCompatDisplayInsets;      } +    /** +     * In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque +     * activity beneath using the given consumer and returns {@code true}. +     */ +    boolean applyOnOpaqueActivityBelow(@NonNull Consumer<ActivityRecord> consumer) { +        return findOpaqueNotFinishingActivityBelow() +                .map(activityRecord -> { +                    consumer.accept(activityRecord); +                    return true; +                }).orElse(false); +    } + +    /** +     * @return The first not finishing opaque activity beneath the current translucent activity +     * if it exists and the strategy is enabled. +     */ +    private Optional<ActivityRecord> findOpaqueNotFinishingActivityBelow() { +        if (!hasInheritedLetterboxBehavior() || mActivityRecord.getTask() == null) { +            return Optional.empty(); +        } +        return Optional.ofNullable(mActivityRecord.getTask().getActivity( +                FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */, +                mActivityRecord /* boundary */, false /* includeBoundary */, +                true /* traverseTopToBottom */)); +    } +      private void inheritConfiguration(ActivityRecord firstOpaque) {          // To avoid wrong behaviour, we're not forcing a specific aspet ratio to activities          // which are not already providing one (e.g. permission dialogs) and presumably also diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 2c4f1663153c..c4269137199e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -271,6 +271,35 @@ public class SizeCompatTests extends WindowTestsBase {      }      @Test +    public void testTranslucentActivitiesWhenUnfolding() { +        mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true); +        setUpDisplaySizeWithApp(2800, 1400); +        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); +        mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier( +                1.0f /*letterboxVerticalPositionMultiplier*/); +        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); +        // We launch a transparent activity +        final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) +                .setLaunchedFromUid(mActivity.getUid()) +                .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) +                .build(); +        doReturn(false).when(translucentActivity).fillsParent(); +        mTask.addChild(translucentActivity); + +        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN); +        spyOn(mActivity); + +        // Halffold +        setFoldablePosture(translucentActivity, true /* isHalfFolded */, false /* isTabletop */); +        verify(mActivity).recomputeConfiguration(); +        clearInvocations(mActivity); + +        // Unfold +        setFoldablePosture(translucentActivity, false /* isHalfFolded */, false /* isTabletop */); +        verify(mActivity).recomputeConfiguration(); +    } + +    @Test      public void testRestartProcessIfVisible() {          setUpDisplaySizeWithApp(1000, 2500);          doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); @@ -3339,14 +3368,20 @@ public class SizeCompatTests extends WindowTestsBase {      } -    private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) { -        final DisplayRotation r = mActivity.mDisplayContent.getDisplayRotation(); +    private void setFoldablePosture(ActivityRecord activity, boolean isHalfFolded, +            boolean isTabletop) { +        final DisplayRotation r = activity.mDisplayContent.getDisplayRotation();          doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();          doReturn(false).when(r).isDeviceInPosture(any(DeviceState.class), anyBoolean());          if (isHalfFolded) { -            doReturn(true).when(r).isDeviceInPosture(DeviceState.HALF_FOLDED, isTabletop); +            doReturn(true).when(r) +                    .isDeviceInPosture(DeviceState.HALF_FOLDED, isTabletop);          } -        mActivity.recomputeConfiguration(); +        activity.recomputeConfiguration(); +    } + +    private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) { +        setFoldablePosture(mActivity, isHalfFolded, isTabletop);      }      @Test |