Merge "Set orientation for boot animation and default display rotation." into tm-qpr-dev

This commit is contained in:
Mariia Sandrikova
2022-12-21 00:37:11 +00:00
committed by Android (Google) Code Review
5 changed files with 99 additions and 7 deletions

View File

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

View File

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

View File

@@ -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 -> {

View File

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

View File

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