Android S 转屏流程

起点:1、自动旋转;2、App设置

接收到传感器传过来的方向值

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation$OrientationListener.java#run

通知WMS更新方向

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java#updateRotationUnchecked

计算使用的方向

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java#rotationForOrientation

调用DisplayRotation更新方向,并且设置2000ms的冻屏超时

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java#updateRotationUnchecked

设置旋转动画

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java#prepareNormalRotationAnimation

开始冻结屏幕

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java#startFreezingDisplay

设置旋转动画ScreenRotationAnimation

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java#setRotationAnimation

通知远端开始旋转,有800ms的超时

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java#startRemoteRotation

远端执行完了以后会回调continueRotation方法

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.jav#continueRotation

通知更新配置信息

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java#sendNewConfiguration

通知ATMS更新配置

frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java#updateGlobalConfigurationLocked

通知每个进程更新配置

frameworks\base\services\core\java\com\android\server\wm\WindowProcessController.java#onConfigurationChanged

通知RootWindowContainer配置更新

frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java#onConfigurationChanged

通知 DisplayContent 配置更新

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java#applyRotation

遍历window,设置 WindowState 的mOrientationChanging为true

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#setOrientationChanging

配置更新完毕,更新window的布局信息

frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java#continueWindowLayout

遍历window,此处会设置window的drawstatus为DRAW_PENDING

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#updateResizingWindowIfNeeded

App会通过finishDrawingLocked方法设置window的drawstatus为COMMIT_DRAW_PENDING

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#finishDrawingLocked

此处会更新window的drawstatus为READY_TO_SHOW

frameworks\base\services\core\java\com\android\server\wm\WindowStateAnimator.java#commitFinishDrawingLocked

App调用relayoutWindow

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java#relayoutWindow

更新window信息

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#updateResizingWindowIfNeeded

如果window是在切换方向,并且drawstatus为READY_TO_SHOW,则设置 WindowState 的mOrientationChanging为false,表示切换方向完毕

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#setOrientationChanging

设置drawstatus为HAS_DRAWN

frameworks\base\services\core\java\com\android\server\wm\WindowState.java#performShowLocked

很多地方会调用WindowAnimator执行动画,并且设置RootWindowContainer.java的mOrientationChangeComplete的属性为true,但是在遍历window的时候,如果window没有旋转完成,又会设置为false。

frameworks\base\services\core\java\com\android\server\wm\WindowAnimator.java#scheduleAnimation

在执行的performSurfacePlacementNoTrace中如果mOrientationChangeComplete为true,就会解除冻屏

frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java#performSurfacePlacementNoTrace

    if (mOrientationChangeComplete) {
        if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
            mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
            mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
            mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
        }
        mWmService.stopFreezingDisplayLocked();
    }

开始解冻屏幕,如果displayContent.getRotationAnimation()不为空,就执行旋转动画

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java#stopFreezingDisplayLocked

最终会调到startAnimation开始初始化动画

frameworks\base\services\core\java\com\android\server\wm\ScreenRotationAnimation.java#dismiss

开始执行动画,并且动画完毕以后会回调onAnimationEnd方法

frameworks\base\services\core\java\com\android\server\wm\ScreenRotationAnimation$SurfaceRotationAnimationController.java#startScreenRotationAnimation

动画执行完毕以后,会回调WMS的updateRotation方法进再次判断是否需要旋转

frameworks\base\services\core\java\com\android\server\wm\ScreenRotationAnimation$SurfaceRotationAnimationController.java#onAnimationEnd

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java#updateRotationUnchecked

App设置方向

App Activity设置方向

frameworks\base\core\java\android\app\Activity.java#setRequestedOrientation

system_server设置方向

frameworks\base\services\core\java\com\android\server\wm\ActivityClientController.java#setRequestedOrientation

ActivityRecord设置方向

frameworks\base\services\core\java\com\android\server\wm\ActivityRecord.java#setRequestedOrientation

ActivityRecord设置方向,后面差不多也是更新配置,等app绘制完成,然后执行旋转动画。

frameworks\base\services\core\java\com\android\server\wm\ActivityRecord.java#setOrientation

WMS中RootWindowContainer.java的performSurfacePlacementNoTrace方法分析

void performSurfacePlacementNoTrace() {
        //更新focus
        if (mWmService.mFocusMayChange) {
            mWmService.mFocusMayChange = false;
            mWmService.updateFocusedWindowLocked(
                    UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
        }

        //更新Surface更改
        try {
            applySurfaceChangesTransaction();
        } catch (RuntimeException e) {
            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
        }

        //更新focus
        mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents()
        mWmService.mSyncEngine.onSurfacePlacement();
        mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
        checkAppTransitionReady(surfacePlacer);

        //更新focus
        if (mWmService.mFocusMayChange) {
            mWmService.mFocusMayChange = false;
            mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                    false /*updateInputWindows*/);
        }

        //更新window大小
        handleResizingWindows();

        //停止冻屏
        if (mOrientationChangeComplete) {
            if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
                mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
                mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
                mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
            }
            mWmService.stopFreezingDisplayLocked();
        }

        //更新InputWindow
        forAllDisplays(dc -> {
            dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
            dc.updateSystemGestureExclusion();
            dc.updateTouchExcludeRegion();
        });

未完成

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java#applySurfaceChangesTransaction

You May Also Like

About the Author: ice.zhai

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注