上篇博客中我们一直提到updateRotationUnchecked函数,这篇博客我们就来分析下这个函数,这个函数可以说是旋转屏幕的一个核心函数,我们主要看下updateRotationUncheckedLocked和sendNewConfiguration函数,当updateRotationUncheckedLocked返回true代表设备已经旋转,这个时候要调用sendNewConfiguration函数通知AMS来使相应的Activity重新Launch等。
public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
long origId = Binder.clearCallingIdentity();
boolean changed;
synchronized(mWindowMap) {
changed = updateRotationUncheckedLocked(false);
if (!changed || forceRelayout) {
getDefaultDisplayContentLocked().layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
}
if (changed || alwaysSendConfiguration) {
sendNewConfiguration();//后续分析
}
Binder.restoreCallingIdentity(origId);
}
sendNewConfiguration我们放到下篇博客分析,这里我们先分析updateRotationUncheckedLocked函数。
PhoneWindowManager的rotationForOrientationLw获取rotation
下面是部分代码,我们先调用PhoneWindowManager的rotationForOrientationLw函数来获取rotation,然后与之前的mRotation对比是否有变化,没有变化直接返回false。有变化将mRotation重新赋值。
......
int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
mForcedAppOrientation, rotation);
if (mRotation == rotation && mAltOrientation == altOrientation) {
// No change.
return false;
}
mRotation = rotation;
mAltOrientation = altOrientation;
......
PhoneWindowManager的rotationForOrientationLw函数我们就不分析了,就是获取sensor的rotation,然后计算返回我们需要的rotation。我们继续看updateRotationUncheckedLocked函数的剩下代码。
updateDisplayAndOrientationLocked DisplayInfo数据放入display中
在updateRotationUncheckedLocked中还调用了updateDisplayAndOrientationLocked函数,我们也来看下,这个函数把各种数据更新下放到DisplayInfo中,最后调用了DisplayManagerService的setDisplayInfoOverrideFromWindowManager函数
DisplayInfo updateDisplayAndOrientationLocked() {
......
// Update application display metrics.
final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
synchronized(displayContent.mDisplaySizeLock) {
displayInfo.rotation = mRotation;//旋转
displayInfo.logicalWidth = dw;
displayInfo.logicalHeight = dh;
displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
displayInfo.appWidth = appWidth;
displayInfo.appHeight = appHeight;
displayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
displayInfo.getAppMetrics(mDisplayMetrics);
if (displayContent.mDisplayScalingDisabled) {
displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
} else {
displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
}
mD