屏幕旋转流程

什么时候开始冻屏? 冻屏做什么? 冻屏什么时候结束? 冻屏动画是什么样的?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>

相关推荐
xiangpanf4 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx6 小时前
安卓线程相关
android
消失的旧时光-19437 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon8 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon8 小时前
VSYNC 信号完整流程2
android
dalancon8 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013849 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android9 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才10 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶11 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle