Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6e2e107 authored by Massimo Carli's avatar Massimo Carli
Browse files

Fix translucent activities when unfolding

In the unfold process only the top activity bounds were calculated.
Now we update the bounds of the first opaque activity beneath.

Bug: 261721427
Test: Run `atest SizeCompatTests`

Change-Id: I5895a417aecdc66d1b17184cbe700ef1da5e1148
parent 25e0c530
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -8293,8 +8293,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    void recomputeConfiguration() {
        // 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() {
        return inTransitionSelfOrParent();
+29 −0
Original line number Diff line number Diff line
@@ -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
+39 −4
Original line number Diff line number Diff line
@@ -270,6 +270,35 @@ public class SizeCompatTests extends WindowTestsBase {
        verify(mActivity).isFinishing();
    }

    @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);
@@ -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