屏幕旋转流程

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

相关推荐
No Silver Bullet22 分钟前
Android Studio如何开启离线编译模式
android
vocal2 小时前
【Android 构建优化】R8 : 混淆,压缩与优化
android
叽哥2 小时前
Kotlin学习第 7 课:Kotlin 空安全:解决空指针问题的核心机制
android·java·kotlin
诺诺Okami2 小时前
Android Framework-Launcher-默认布局的加载
android
狂浪天涯3 小时前
Android Security | SEAndroid 的主体
android
马 孔 多 在下雨6 小时前
安卓旋转屏幕后如何防止数据丢失-ViewModel入门
android
Just_Paranoid11 小时前
【Settings】恢复出厂设置密码校验
android·python·settings·sha256·hmac-sha256
肥肥呀呀呀14 小时前
flutter配置Android gradle kts 8.0 的打包名称
android·flutter
平生不喜凡桃李16 小时前
C++ 异常
android·java·c++
Propeller18 小时前
【Android】View 交互的事件处理机制
android·java