1、需求
客户动态设置屏幕的旋转方向,下次开机保持设置的屏幕方向,开关机动画也要跟着旋转。
2、分析
如果开关机动画也要跟着旋转,就不跟再LocalDisplayAdapter.java里面改了,因为开关机动画已经基本走完,需要在SurfaceFlinger.cpp里面改动
3、撸起袖子开干
设置里面添加菜单的流程代码省略,这部分已经有成熟的demo可以参考,我是使用persist.vendor.orientation属性来控制屏幕的显示方向,取值0 90 180 270。
SurfaceFlinger.cpp修改
在processDisplayHotplugEventsLocked里面修改
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
for (const auto& event : mPendingHotplugEvents) {
const std::optional<DisplayIdentificationInfo> info =
getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
if (!info) {
continue;
}
+char rotationvalue[PROPERTY_VALUE_MAX] = "";;
+property_get("persist.vendor.orientation", rotationvalue, "-1");
+int rotation = atoi(rotationvalue);
+ALOGI("Primary Display Orientation is set to rotation %2d.", rotation);
+switch (rotation) {
+ case 0:
+ internalDisplayOrientation = ui::ROTATION_0;
+ break;
+ case 90:
+ internalDisplayOrientation = ui::ROTATION_90;
+ break;
+ case 180:
+ internalDisplayOrientation = ui::ROTATION_180;
+ break;
+ case 270:
+ internalDisplayOrientation = ui::ROTATION_270;
+ break;
+ default:
+ break;
+}
const DisplayId displayId = info->id;
const auto it = mPhysicalDisplayTokens.find(displayId);
添加如上代码功能就OK了。
不过中间遇到了俩个问题
1、persist.vendor.orientation 属性设置值失败
android11的权限整的很让人无语,对属性的控制更加严格,我对比了系统里面一些属性配置,发现了debug_prop类型,于是在device/rockchip/sepolicy/private/property_contexts文件中增加
persist.vendor.orientation u:object_r:debug_prop:s0 问题得到解决。
2、设置了旋转方向后,有时候开机方向还是默认方向
logcat看了发现偶尔会读取不到persist.vendor.orientation属性值,一般这种问题都是磁盘分区加密引起的,关闭磁盘分区加密就可以解决。
确认磁盘是否加密方法
adb shell getprop ro.crypto.state
显示encrypted说明已加密,
显示unencrypte说明未加密
关闭磁盘读取加密方法
device/rockchip/common/scripts/fstab_tools/fstab.in
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065 latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,reservedsize=128M,checkpoint=fs
红色标注的内容去掉即可。
4、看到有朋友问屏幕旋转后,有需求TP也要跟着一起旋转,请看补丁代码
Index: TouchInputMapper.cpp
===================================================================
--- TouchInputMapper.cpp (revision 212)
+++ TouchInputMapper.cpp (revision 213)
@@ -22,6 +22,7 @@
#include "CursorScrollAccumulator.h"
#include "TouchButtonAccumulator.h"
#include "TouchCursorInputMapperCommon.h"
+#include <cutils/properties.h>
namespace android {
@@ -665,6 +666,11 @@
int32_t rawHeight = mRawPointerAxes.getRawHeight();
bool viewportChanged = mViewport != *newViewport;
+ char rotationvalue[PROPERTY_VALUE_MAX] = "";;
+ property_get("persist.vendor.orientation", rotationvalue, "0");
+ int rotation = atoi(rotationvalue);
if (viewportChanged) {
mViewport = *newViewport;
@@ -674,7 +680,33 @@
int32_t naturalPhysicalWidth, naturalPhysicalHeight;
int32_t naturalPhysicalLeft, naturalPhysicalTop;
int32_t naturalDeviceWidth, naturalDeviceHeight;
- switch (mViewport.orientation) {
+ int currentrotation = DISPLAY_ORIENTATION_0;
+ switch (rotation) {
+ case 0:
+ currentrotation = DISPLAY_ORIENTATION_0;
+ break;
+ case 90:
+ currentrotation = DISPLAY_ORIENTATION_90;
+ break;
+ case 180:
+ currentrotation = DISPLAY_ORIENTATION_180;
+ break;
+ case 270:
+ currentrotation = DISPLAY_ORIENTATION_270;
+ break;
+ default:
+ break;
+ }
+ if(currentrotation == DISPLAY_ORIENTATION_0 && mViewport.orientation != currentrotation){
+ rotation = mViewport.orientation;
+ currentrotation = mViewport.orientation;
+ }
+
+ // switch (mViewport.orientation) {
+ switch (currentrotation) {
case DISPLAY_ORIENTATION_90:
naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
@@ -751,6 +783,25 @@
mSurfaceOrientation = DISPLAY_ORIENTATION_0;
}
}
+ ALOGI("Primary Display Orientation is set to rotation %2d.", rotation);
+ switch (rotation) {
+ case 0:
+ mSurfaceOrientation = DISPLAY_ORIENTATION_0;
+ break;
+ case 90:
+ mSurfaceOrientation = DISPLAY_ORIENTATION_90;
+ break;
+ case 180:
+ mSurfaceOrientation = DISPLAY_ORIENTATION_180;
+ break;
+ case 270:
+ mSurfaceOrientation = DISPLAY_ORIENTATION_270;
+ break;
+ default:
+ break;
+ }
// If moving between pointer modes, need to reset some state.
bool deviceModeChanged = mDeviceMode != oldDeviceMode;
@@ -3653,13 +3704,13 @@
}
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
- const float xScaled = (x - mRawPointerAxes.x.minValue) * mXScale;
- const float yScaled = (y - mRawPointerAxes.y.minValue) * mYScale;
-
- return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
- xScaled >= mSurfaceLeft && xScaled <= mSurfaceRight &&
- y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
- yScaled >= mSurfaceTop && yScaled <= mSurfaceBottom;
+ //const float xScaled = (x - mRawPointerAxes.x.minValue) * mXScale;
+ //const float yScaled = (y - mRawPointerAxes.y.minValue) * mYScale;
+ //modify fix dual tp with sync display,second tp funtion is error
+ return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
+ //&& scaledX >= mPhysicalLeft && scaledX <= mPhysicalLeft + mPhysicalWidth
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
+ //&& scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
}
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {