屏幕旋转流程

什么时候开始冻屏? 冻屏做什么? 冻屏什么时候结束? 冻屏动画是什么样的?App进程影响转屏速度?

1.动态日志命令(打开日志所有页面旋转变慢属于正常)

​ (1)命令所在文件 WindowManagerShellCommand.java

​ (2) adb shell wm logging enable-text WM_DEBUG_ORIENTATION

2022-02-25 15:41:22.424 1228-1251/system_process V/WindowManager: With display frozen, orientationChangeComplete=true

2022-02-25 15:41:22.425 1228-1251/system_process D/WindowManager: stopFreezingDisplayLocked: Unfreezing now

2022-02-25 15:41:22.427 1228-1251/system_process I/WindowManager: Screen frozen for +2s53ms due to Window{c55016b u0 com.example.android.persistence/com.example.android.observability.ui.TestActivity}
2. Sensor的使能 / 判断:

​ (1)使能 DisplayRotation.java : mOrientationListener.enable mOrientationListener.disable

(2)Gsensor的判断和优化:

google算法: Android转屏流程与优化(Google转屏算法)_旋转屏幕速度优化-CSDN博客

源码参考: driveronly 版本:http://opengrok.tclcom.com:8080/mt6762-s0-v1.0-driveronly/xref/frameworks/base/services/core/java/com/android/server/wm/WindowOrientationListener.java

```

仰角的计算:

final int tiltAngle = (int) Math.round(

Math.asin(z / magnitude) * RADIANS_TO_DEGREES);

旋转角度的计算:

int orientationAngle = (int) Math.round(

-Math.atan2(-x, y) * RADIANS_TO_DEGREES);

```

内部的优化参考:

FR(10361935)AccelSensorJudge(g sensor),OrientationSensorJudge的优化不在这个FR里面

目前google算法有几个比较大的缺陷: 1、由于gsensor是只有一个方向的感应,即垂直向下的重力加速度感应,那么如果在旋转时加上另一个加速度(上下左右前后都会有影响), 这个gsensor的数据返回给上层的就会不准确,目前google算法并未有精准的角度计算。 2、由于上述缺陷,google算法会对加速度等进行规避,如果出现加速度,就延迟300-500ms,也就导致了上层最终识别方向google算法就会有300-500ms的延迟。3、方向识别比较保守:如角度忽略过多,传感器出来速度以1/4的速率变化

​ 触发 onSensorChanged --> DisplayRotation::OrientationListener::onProposedRotationChanged

3. 什么时候开始冻屏?

(1) sensor感应 --> WMS.updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */);

​ WMS.updateRotation--->

​ DisplayContent.updateRotationUnchecked();--->

​ DisplayRotation.updateRotationUnchecked ---> {

​ mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,

​ mDisplayContent, WINDOW_FREEZE_TIMEOUT_DURATION); --->设置冻屏超时2秒

​ prepareNormalRotationAnimation --->开始冻屏

​ startRemoteRotation ---> mRemoteRotationCallback--> DisplayRotation::continueRotation --> sendNewConfiguration

​ }

![](/data/nishome/td/jimeng.zhang/Desktop/屏幕旋转/start_screen_freeze.png)

4.冻屏做什么?

WindowManagerService.java

startFreezingDisplay-->{

1) 冻结输入

​ mInputManagerCallback.freezeInputDispatchingLw(); ---->>输入事件停止分发 InputDispatcher::setInputDispatchMode(bool enabled, bool frozen)

2)停止动画

​ displayContent.mAppTransition.freeze();

3)设置转屏动画

​ displayContent.setRotationAnimation --->> ScreenRotationAnimation//截屏旋转

​ 动画定制(http://sz.gerrit.tclcom.com:8080/c/mtk/platform/frameworks/base/+/354036)

​ }

5.冻屏什么时候结束?

1)超时 或 mOrientationChangeComplete 各window绘制完成

/** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */

static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;

2)mOrientationChangeComplete 状态的维护:

//WindowAnimator wms的单例,响应全局动画 :animate(long frameTimeNs, long vsyncId)

WindowAnimator.java: root.mOrientationChangeComplete = true;

//configuration change时

WindowState : mWmService.mRoot.mOrientationChangeComplete = false;

//Keep track of animations and surface operations for a single WindowState.

WindowStateAnimator : w.mWmService.mRoot.mOrientationChangeComplete = false;

开始旋转时 WindowState :: onConfigurationChanged, 对mOrientationChangeComplete 状态的维护:

![](/data/nishome/td/jimeng.zhang/Desktop/屏幕旋转/windowstate_onConfiguration.png)

绘制没有完成时: WindowStateAnimator : :prepareSurfaceLocked

```

if (w.getOrientationChanging()) {

if (!w.isDrawn()) {

if (w.mDisplayContent.waitForUnfreeze(w)) {

w.mWmService.mRoot.mOrientationChangeComplete = false;

```

调用栈:

prepareSurfaceLocked:621, WindowStateAnimator (com.android.server.wm)

prepareSurfaces:5575, WindowState (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:6957, ActivityRecord (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:4046, Task (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:644, DisplayArea$Dimmable (com.android.server.wm)

prepareSurfaces:2469, WindowContainer (com.android.server.wm)

prepareSurfaces:644, DisplayArea$Dimmable (com.android.server.wm)

prepareSurfaces:4991, DisplayContent (com.android.server.wm)

applySurfaceChangesTransaction:4443, DisplayContent (com.android.server.wm)

applySurfaceChangesTransaction:1076, RootWindowContainer (com.android.server.wm)

performSurfacePlacementNoTrace:852, RootWindowContainer (com.android.server.wm)

performSurfacePlacement:805, RootWindowContainer (com.android.server.wm)

performSurfacePlacementLoop:177, WindowSurfacePlacer (com.android.server.wm)

performSurfacePlacement:126, WindowSurfacePlacer (com.android.server.wm)

performSurfacePlacement:115, WindowSurfacePlacer (com.android.server.wm)

continueLayout:97, WindowSurfacePlacer (com.android.server.wm)

continueWindowLayout:4497, ActivityTaskManagerService (com.android.server.wm)

continueRotation:702, DisplayRotation (com.android.server.wm)

6.转屏Boost:

/// M: MTK Power: Enable rotation boost

mPowerHalManager.setRotationBoost(true);

public static final int ROTATE_BOOST_TIME = 2000;

48 <scenario powerhint="MTKPOWER_HINT_APP_ROTATE">

49 <data cmd="PERF_RES_CPUFREQ_MIN_CLUSTER_0" param1="3000000"></data>

50 <data cmd="PERF_RES_CPUFREQ_MIN_CLUSTER_1" param1="3000000"></data>

51 <data cmd="PERF_RES_DRAM_OPP_MIN" param1="0"></data>

52 <data cmd="PERF_RES_SCHED_UCLAMP_MIN_TA" param1="100"></data>

53 <data cmd="PERF_RES_SCHED_BOOST" param1="1"></data>

54 </scenario>

相关推荐
程序视点2 小时前
Escrcpy 3.0投屏控制软件使用教程:无线/有线连接+虚拟显示功能等
android
东京老树根5 小时前
Android - 用Scrcpy 将手机投屏到Windows电脑上
android
Wgllss6 小时前
完整烟花效果,Compose + 协程 + Flow + Channel 轻松实现
android·架构·android jetpack
扛麻袋的少年6 小时前
6.Kotlin的Duration类
android·开发语言·kotlin
独自破碎E6 小时前
得物25年春招-安卓部分笔试题1
android
雨白7 小时前
Android 自定义 View:精通文字的测量与高级排版
android
Jasonakeke7 小时前
【重学MySQL】八十八、8.0版本核心新特性全解析
android·数据库·mysql
一条上岸小咸鱼9 小时前
Kotlin 类型检查与转换
android·kotlin
闲暇部落10 小时前
android studio配置 build
android·android studio·build
_祝你今天愉快11 小时前
Android FrameWork - Zygote 启动流程分析
android