最近遇到一个问题:相册打开一张图片,横竖屏旋转时,有的图片旋转时四周背景色是白色,有的则是黑色的。Why? 难不成背景色与图片相关? -- 11.0的问题,10.0并无
对WMS模块了解一些的人应该都知道,横竖屏旋转是系统动画,旋转方式以及背景色一般都是由系统设定的。
本篇就基于这个问题分析下R的横竖屏旋转时四周背景色的相关流程。
关键文件:
frameworks\base\services\core\java\com\android\server\wm\ScreenRotationAnimation.java
frameworks\base\services\core\java\com\android\server\wm\utils\RotationAnimationUtils.java
首先总结下背景色设置的总体流程,这样大家有一个大概的了解:
横竖屏旋转时的背景色是一个Surface--"BackColorSurface",定义在ScreenRotationAnimation类中,该Surface由冻屏时的截屏确定start color,然后由更新方向后的最新界面确定end color,然后在旋转动画开始时,BackColorSurface也同时执行从start color—end color的颜色更改动画。
这是R新添加的小功能,可能是为了在横竖屏切换时不那么生硬??? 比如Q的白色界面在横竖屏旋转背景色都是黑色。
下面来一步步梳理下:
本篇文章不关心其他内容,直接从开始冻屏的地方开始分析:ScreenRotationAnimation.ScreenRotationAnimation
Step 1. ScreenRotationAnimation.ScreenRotationAnimation
/** Only used for custom animations and not screen rotation. */
private SurfaceControl mEnterBlackFrameLayer;
/** This layer contains the actual screenshot that is to be faded out. */
private SurfaceControl mScreenshotLayer;
/**
* Only used for screen rotation and not custom animations. Layered behind all other layers
* to avoid showing any "empty" spots
*/
private SurfaceControl mBackColorSurface;
private BlackFrame mEnteringBlackFrame;
private SurfaceRotationAnimationController mSurfaceRotationAnimationController;
/** Intensity of light/whiteness of the layout before rotation occurs. */
private float mStartLuma;
/** Intensity of light/whiteness of the layout after rotation occurs. */
private float mEndLuma;
ScreenRotationAnimation(DisplayContent displayContent, @Surface.Rotation int originalRotation) {
...... // 省略一些无关的代码
// 这个我记得以前分析过,就是动画的辅助类,后面会涉及到
mSurfaceRotationAnimationController = new SurfaceRotationAnimationController();
// Check whether the current screen contains any secure content.
final boolean isSecure = displayContent.hasSecureWindowOnScreen();
final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
try {
// 这个就是横竖屏旋转时的背景Surface,colorLayer类型
mBackColorSurface = displayContent.makeChildSurface(null)
.setName("BackColorSurface")
.setColorLayer()
.setCallsite("ScreenRotationAnimation")
.build();
// RotationLayer: 冻屏时显示在最上方的截屏
mScreenshotLayer = displayContent.makeOverlay()
.setName("RotationLayer")
.setBufferSize(mWidth, mHeight)
.setSecure(isSecure)
.setCallsite("ScreenRotationAnimation")
.build();
mEnterBlackFrameLayer = displayContent.makeOverlay()
.setName("EnterBlackFrameLayer")
.setContainerLayer()
.setCallsite("ScreenRotationAnimation")
.build(); // 针对custom animation的背景色,略
// In case display bounds change, sc