当前位置: 首页 > news >正文

Android T about screen rotation(二)

需求:客户因为模具问题,屏幕方向需要动态的变动.(方向: 0 , 90 , 180 ,270)

拆分:设备开机过程中图像显示可分为三个阶段,boot logo(1)->kernel logo(2),这一段的处理需要驱动层,所以暂时忽略.

开机动画 Bootanimation(3)阶段 和 Home Launcher应用显示(4)阶段是需要修改的.

因为是动态的,有涉及到cpp部分,一般用系统属性保存:persist.customer.set.orientation=0

Bootanimation
./frameworks/base/cmds/bootanimation/BootAnimation.cpp/**
* readyToRun()负责构建开机动画,进入readyToRun()中 就来加载显示每一帧动画
*
* createSurface()负责绘制开机动画页面
*/status_t BootAnimation::readyToRun() {mAssets.addDefaultAssets();mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();if (mDisplayToken == nullptr)return NAME_NOT_FOUND;DisplayMode displayMode;const status_t error =SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &displayMode);if (error != NO_ERROR)return error;mMaxWidth = android::base::GetIntProperty("ro.surface_flinger.max_graphics_width", 0);mMaxHeight = android::base::GetIntProperty("ro.surface_flinger.max_graphics_height", 0);ui::Size resolution = displayMode.resolution;resolution = limitSurfaceSize(resolution.width, resolution.height);+    //add text
+    char cOrientation [PROPERTY_VALUE_MAX];
+    property_get("persist.customer.set.orientation",cOrientation,"0");
+    int temp_orientation = atoi(cOrientation);
+
+    SurfaceComposerClient::Transaction t;
+
+    int temp_width = 0;
+    int temp_height = 0;
+
+    if(temp_orientation == 90){
+        temp_width = resolution.getHeight();
+        temp_height = resolution.getWidth();
+        Rect destRect(temp_width, temp_height);
+        t.setDisplayProjection(mDisplayToken, ui::ROTATION_90, destRect, destRect);
+        ALOGD("BootAnimation rotation is 90");
+    }else if(temp_orientation == 180){
+        Rect destRect(temp_width, temp_height);
+        t.setDisplayProjection(mDisplayToken, ui::ROTATION_180, destRect, destRect);
+        ALOGD("BootAnimation rotation is 180");
+    }else if(temp_orientation == 270){
+        temp_width = resolution.getHeight();
+        temp_height = resolution.getWidth();
+        Rect destRect(temp_width, temp_height);
+        t.setDisplayProjection(mDisplayToken, ui::ROTATION_270, destRect, destRect);
+        ALOGD("BootAnimation rotation is 270");
+    }// create the native surfacesp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
-
-    SurfaceComposerClient::Transaction t;
+    //add text// this guest property specifies multi-display IDs to show the boot animation// multiple ids can be set with comma (,) as separator, for example:...
}//系统自带根据ro.bootanim.set_orientation_<display_id> 旋转屏幕动画方向
// 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.
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;
}
applications

动画的屏幕方向,一阶段是由上面的代码决定,二阶段由Framework display决定

frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java+    private int mCustomerRotation = Surface.ROTATION_0;//add text@VisibleForTestingDisplayRotation(WindowManagerService service, DisplayContent displayContent,DisplayAddress displayAddress, DisplayPolicy displayPolicy,DisplayWindowSettings displayWindowSettings, Context context, Object lock,@NonNull DeviceStateController deviceStateController) {mService = service;mDisplayContent = displayContent;...
+        //add text
+        int temp_orientation = SystemProperties.getInt("persist.customer.set.orientation", 0);
+        if (temp_orientation == 0) {
+            mCustomerRotation = Surface.ROTATION_0;
+        } else if (temp_orientation == 90) {
+            mCustomerRotation = Surface.ROTATION_90;
+        } else if (temp_orientation == 180) {
+            mCustomerRotation = Surface.ROTATION_180;
+        } else if (temp_orientation == 270) {
+            mCustomerRotation = Surface.ROTATION_270;
+        }
+        mRotation = mCustomerRotation;//end replace
+        //add text
+       //观察 user_rotationif (isDefaultDisplay) {final Handler uiHandler = UiThread.getHandler();mOrientationListener =new OrientationListener(mContext, uiHandler, defaultRotation);mOrientationListener.setCurrentRotation(mRotation);mSettingsObserver = new SettingsObserver(uiHandler);mSettingsObserver.observe();if (mSupportAutoRotation && mContext.getResources().getBoolean(R.bool.config_windowManagerHalfFoldAutoRotateOverride)) {mFoldController = new FoldController();} else {mFoldController = null;}} else {mFoldController = null;}}boolean updateRotationUnchecked(boolean forceUpdate) {final int displayId = mDisplayContent.getDisplayId();...final int oldRotation = mRotation;final int lastOrientation = mLastOrientation;
-        int rotation = rotationForOrientation(lastOrientation, oldRotation);
+        int rotation = mCustomerRotation;//rotationForOrientation(lastOrientation, oldRotation);//add text// Use the saved rotation for tabletop mode, if set.if (mFoldController != null && mFoldController.shouldRevertOverriddenRotation()) {int prevRotation = rotation;...}@Surface.Rotationint rotationForOrientation(@ScreenOrientation int orientation,@Surface.Rotation int lastRotation) {...//关于这里的判断,自己可以根据需求旋转条件  
+        //add text
+        if(true){
+            return mCustomerRotation;
+        }
+        //add text
+if (isFixedToUserRotation()) {return mUserRotation;}}/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java    @ScreenOrientation@Overrideint getOrientation() {
+        //add text
+        int mCustomerRotation = 0;
+        int temp_orientation = SystemProperties.getInt("persist.customer.set.orientation", 0);
+        if (temp_orientation == 0) {
+            mCustomerRotation = Surface.ROTATION_0;
+            return mCustomerRotation;
+        } else if (temp_orientation == 90) {
+            mCustomerRotation = Surface.ROTATION_90;
+            return mCustomerRotation;
+        } else if (temp_orientation == 190) {
+            mCustomerRotation = Surface.ROTATION_180;
+            return mCustomerRotation;
+        } else if (temp_orientation == 270) {
+            mCustomerRotation = Surface.ROTATION_270;
+            return mCustomerRotation;
+        }
+        //add textif (mWmService.mDisplayFrozen) {if (mWmService.mPolicy.isKeyguardLocked()) {//是否允许设备通过加速器(G-sensor)在所有四个方向自动旋转屏幕 
/frameworks/base/core/res/res/values/config.xml<!-- If true, the screen can be rotated via the accelerometer in all 4rotations as the default behavior. -->
-    <bool name="config_allowAllRotations">false</bool>
+    <bool name="config_allowAllRotations">true</bool><!-- If true, the direction rotation is applied to get to an application's requestedorientation is reversed.  Normally, the model is that landscape is
about SurfaceFlinger

SurfaceFlinger是Android系统中负责屏幕显示内容合成的服务,它接收来自多个应用程序和系统服务的图像缓冲区,
根据它们的位置、大小、透明度、Z轴顺序等属性,将它们合成到一个最终的缓冲区中,然后发送到显示设备上

修改getPhysicalDisplayOrientation 显示方向,也可以实现上面的效果.
如果要动态的,就要用到系统属性,但是可能会遇到针对数据分区加密导致的开机时无法读取系统属性问题.
如何解决,(修改init.mount_all_early.rc和fstab.in)参考:RK平台android12 动态调整屏幕方向

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cppui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId,bool isPrimary) const {/*const auto id = PhysicalDisplayId::tryCast(displayId);if (!id) {return ui::ROTATION_0;}if (getHwComposer().getComposer()->isSupported(Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {switch (getHwComposer().getPhysicalDisplayOrientation(*id)) {case Hwc2::AidlTransform::ROT_90:return ui::ROTATION_90;case Hwc2::AidlTransform::ROT_180:return ui::ROTATION_180;case Hwc2::AidlTransform::ROT_270:return ui::ROTATION_270;default:return ui::ROTATION_0;}}if (isPrimary) {using Values = SurfaceFlingerProperties::primary_display_orientation_values;switch (primary_display_orientation(Values::ORIENTATION_0)) {case Values::ORIENTATION_90:return ui::ROTATION_90;case Values::ORIENTATION_180:return ui::ROTATION_180;case Values::ORIENTATION_270:return ui::ROTATION_270;default:break;}}*/return ui::ROTATION_270;
}void SurfaceFlinger::startBootAnim() {// Start boot animation service by setting a property mailbox// if property setting thread is already running, Start() will be just a NOPmStartPropertySetThread->Start();// Wait until property was setif (mStartPropertySetThread->join() != NO_ERROR) {ALOGE("Join StartPropertySetThread failed!");}
}

SurfaceFlinger的原理
Android显示系统SurfaceFlinger详解 超级干货
正点原子RK3588开发板Android系统屏幕显示方向配置

http://www.lryc.cn/news/425967.html

相关文章:

  • qt反射之类反射、方法反射、字段反射
  • 服务器数据恢复—raid5阵列离线硬盘强制上线失败如何恢复数据?
  • FastAPI+Vue3零基础开发ERP系统项目实战课 20240815上课笔记 列表和字典相关方法的学习和练习
  • 基于微信小程序的诗词智能学习系统的设计与实现(全网独一无二,24年最新定做)
  • httplib库:用C++11搭建轻量级HTTP服务器
  • 基于嵌入式C++、SQLite、MQTT、Modbus和Web技术的工业物联网网关:从边缘计算到云端集成的全栈解决方案设计与实现
  • Chapter 38 设计模式
  • Redis5主备安装-Redis
  • C++票据查验、票据ocr、文字识别
  • pytest.ini介绍
  • Vue项目打包成桌面应用
  • DEFAULT_JOURNAL_IOPRIO
  • 【阿卡迈防护分析】Vueling航空Akamai破盾实战
  • 使用AWS Lambda轻松开启Amazon Rekognition之旅
  • 如何获取VS Code扩展的版本更新信息
  • Python开源项目周排行 2024年第13周
  • day04--js的综合案例
  • 【产品经理】定价策略
  • webrtc学习笔记3
  • Transformer架构;Encoder-Decoder;Padding Mask;Sequence Mask;
  • 【leetcode详解】特殊数组II : 一题代表了一类问题(前缀和思想)
  • SQL每日一练-0814
  • Android持久化技术—文件存储
  • 动手学深度学习(pytorch)学习记录12-激活函数[学习记录]
  • 微服务实战系列之玩转Docker(十)
  • Mysql(四)---增删查改(进阶)
  • SOAP @WebService WSDL
  • 【Qt】QWidget的toolTip属性
  • 【操作系统】什么是进程?什么是线程?两者有什么区别(面试常考!!!)
  • AI -- Machine Learning