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

Commit a166f012 authored by Mariia Sandrikova's avatar Mariia Sandrikova
Browse files

Set orientation for boot animation and default display rotation.

Change the default display rotation value and boot animation orientation to the value specified in the sysprop ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0, ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270. If the value isn't specified or is ORIENTATION_0, nothing will be changed.

This is needed to support having default rotation behavior and boot animation in orientation different from the natural device orientation. For example, on tablets that may want to keep natural orientation
portrait for applications compatibility but have landscape orientation as a default choice from the UX perspective.

Bug: 260627934
Test: manual test with all 4 values and atest WmTests still pass
Change-Id: I322919999ef787ff2c149293d7e1c7e669796c9a
parent 8a83f07a
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -583,6 +583,15 @@ status_t BootAnimation::readyToRun() {
    mFlingerSurface = s;
    mTargetInset = -1;

    // Rotate the boot animation according to the value specified in the sysprop
    // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0,
    // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
    // If the value isn't specified or is ORIENTATION_0, nothing will be changed.
    // This is needed to support having boot animation in orientations different from the natural
    // device orientation. For example, on tablets that may want to keep natural orientation
    // portrait for applications compatibility and to have the boot animation in landscape.
    rotateAwayFromNaturalOrientationIfNeeded();

    projectSceneToWindow();

    // Register a display event receiver
@@ -596,6 +605,50 @@ status_t BootAnimation::readyToRun() {
    return NO_ERROR;
}

void BootAnimation::rotateAwayFromNaturalOrientationIfNeeded() {
    const auto orientation = parseOrientationProperty();

    if (orientation == ui::ROTATION_0) {
        // Do nothing if the sysprop isn't set or is set to ROTATION_0.
        return;
    }

    if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
        std::swap(mWidth, mHeight);
        std::swap(mInitWidth, mInitHeight);
        mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight);
    }

    Rect displayRect(0, 0, mWidth, mHeight);
    Rect layerStackRect(0, 0, mWidth, mHeight);

    SurfaceComposerClient::Transaction t;
    t.setDisplayProjection(mDisplayToken, orientation, layerStackRect, displayRect);
    t.apply();
}

ui::Rotation BootAnimation::parseOrientationProperty() {
    const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
    if (displayIds.size() == 0) {
        return ui::ROTATION_0;
    }
    const auto displayId = displayIds[0];
    const auto syspropName = [displayId] {
        std::stringstream ss;
        ss << "ro.bootanim.set_orientation_" << displayId.value;
        return ss.str();
    }();
    const auto syspropValue = android::base::GetProperty(syspropName, "ORIENTATION_0");
    if (syspropValue == "ORIENTATION_90") {
        return ui::ROTATION_90;
    } else if (syspropValue == "ORIENTATION_180") {
        return ui::ROTATION_180;
    } else if (syspropValue == "ORIENTATION_270") {
        return ui::ROTATION_270;
    }
    return ui::ROTATION_0;
}

void BootAnimation::projectSceneToWindow() {
    glViewport(0, 0, mWidth, mHeight);
    glScissor(0, 0, mWidth, mHeight);
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#include <utils/Thread.h>
#include <binder/IBinder.h>

#include <ui/Rotation.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

@@ -200,6 +202,8 @@ private:
    ui::Size limitSurfaceSize(int width, int height) const;
    void resizeSurface(int newWidth, int newHeight);
    void projectSceneToWindow();
    void rotateAwayFromNaturalOrientationIfNeeded();
    ui::Rotation parseOrientationProperty();

    bool shouldStopPlayingPart(const Animation::Part& part, int fadedFramesCount,
                               int lastDisplayedProgress);
+1 −1
Original line number Diff line number Diff line
@@ -1125,7 +1125,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }

        mDisplayPolicy = new DisplayPolicy(mWmService, this);
        mDisplayRotation = new DisplayRotation(mWmService, this);
        mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address);

        mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH,
                newFoldState -> {
+35 −4
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import android.provider.Settings;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayAddress;
import android.view.IWindowManager;
import android.view.Surface;
import android.window.TransitionRequestInfo;
@@ -211,15 +212,16 @@ public class DisplayRotation {
    private boolean mDemoHdmiRotationLock;
    private boolean mDemoRotationLock;

    DisplayRotation(WindowManagerService service, DisplayContent displayContent) {
        this(service, displayContent, displayContent.getDisplayPolicy(),
    DisplayRotation(WindowManagerService service, DisplayContent displayContent,
            DisplayAddress displayAddress) {
        this(service, displayContent, displayAddress, displayContent.getDisplayPolicy(),
                service.mDisplayWindowSettings, service.mContext, service.getWindowManagerLock());
    }

    @VisibleForTesting
    DisplayRotation(WindowManagerService service, DisplayContent displayContent,
            DisplayPolicy displayPolicy, DisplayWindowSettings displayWindowSettings,
            Context context, Object lock) {
            DisplayAddress displayAddress, DisplayPolicy displayPolicy,
            DisplayWindowSettings displayWindowSettings, Context context, Object lock) {
        mService = service;
        mDisplayContent = displayContent;
        mDisplayPolicy = displayPolicy;
@@ -235,6 +237,8 @@ public class DisplayRotation {
        mDeskDockRotation = readRotation(R.integer.config_deskDockRotation);
        mUndockedHdmiRotation = readRotation(R.integer.config_undockedHdmiRotation);

        mRotation = readDefaultDisplayRotation(displayAddress);

        if (isDefaultDisplay) {
            final Handler uiHandler = UiThread.getHandler();
            mOrientationListener = new OrientationListener(mContext, uiHandler);
@@ -248,6 +252,33 @@ public class DisplayRotation {
        }
    }

    // Change the default value to the value specified in the sysprop
    // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0,
    // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
    // If the value isn't specified or is ORIENTATION_0, nothing will be changed.
    // This is needed to support having default orientation different from the natural
    // device orientation. For example, on tablets that may want to keep natural orientation
    // portrait for applications compatibility but have landscape orientation as a default choice
    // from the UX perspective.
    @Surface.Rotation
    private int readDefaultDisplayRotation(DisplayAddress displayAddress) {
        if (!(displayAddress instanceof DisplayAddress.Physical)) {
            return Surface.ROTATION_0;
        }
        final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) displayAddress;
        String syspropValue = SystemProperties.get(
                "ro.bootanim.set_orientation_" + physicalAddress.getPhysicalDisplayId(),
                "ORIENTATION_0");
        if (syspropValue.equals("ORIENTATION_90")) {
            return Surface.ROTATION_90;
        } else if (syspropValue.equals("ORIENTATION_180")) {
            return Surface.ROTATION_180;
        } else if (syspropValue.equals("ORIENTATION_270")) {
            return Surface.ROTATION_270;
        }
        return Surface.ROTATION_0;
    }

    private int readRotation(int resID) {
        try {
            final int rotation = mContext.getResources().getInteger(resID);
+6 −2
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.os.PowerManagerInternal;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.view.DisplayAddress;
import android.view.Surface;
import android.view.WindowManager;

@@ -101,6 +102,7 @@ public class DisplayRotationTests {
    private static WindowManagerService sMockWm;
    private DisplayContent mMockDisplayContent;
    private DisplayPolicy mMockDisplayPolicy;
    private DisplayAddress mMockDisplayAddress;
    private Context mMockContext;
    private Resources mMockRes;
    private SensorManager mMockSensorManager;
@@ -1091,9 +1093,11 @@ public class DisplayRotationTests {
            when(mMockResolver.acquireProvider(Settings.AUTHORITY))
                    .thenReturn(mFakeSettingsProvider.getIContentProvider());

            mMockDisplayAddress = mock(DisplayAddress.class);

            mMockDisplayWindowSettings = mock(DisplayWindowSettings.class);
            mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayPolicy,
                    mMockDisplayWindowSettings, mMockContext, new Object());
            mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayAddress,
                    mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object());
            reset(sMockWm);

            captureObservers();