Android屏幕旋转流程(二)

然后经过了一系列的forallwindows操作,最后运行到了mapplysurfacechangestransaction

####26.displaycontent->mapplysurfacechangestransaction

638    private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
...
751        w.updateResizingWindowIfNeeded();
752    };

27.windowstate->resizingwindowifneed

1256    void updateResizingWindowIfNeeded() {
1257        final WindowStateAnimator winAnimator = mWinAnimator;
1258        if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) {
1259            return;
1260        }
1261
1262        final Task task = getTask();
1263        // In the case of stack bound animations, the window frames will update (unlike other
1264        // animations which just modify various transformation properties). We don't want to
1265        // notify the client of frame changes in this case. Not only is it a lot of churn, but
1266        // the frame may not correspond to the surface size or the onscreen area at various
1267        // phases in the animation, and the client will become sad and confused.
1268        if (task != null && task.mStack.isAnimatingBounds()) {
1269            return;
1270        }
1271
1272        setReportResizeHints();
1273        boolean configChanged = isConfigChanged();
1274        if (DEBUG_CONFIGURATION && configChanged) {
1275            Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration());
1276        }
1277
1278        final boolean dragResizingChanged = isDragResizeChanged()
1279                && !isDragResizingChangeReported();
1280
1281        if (localLOGV) Slog.v(TAG_WM, "Resizing " + this + ": configChanged=" + configChanged
1282                + " dragResizingChanged=" + dragResizingChanged + " last=" + mLastFrame
1283                + " frame=" + mFrame);
1284
1285        // We update mLastFrame always rather than in the conditional with the last inset
1286        // variables, because mFrameSizeChanged only tracks the width and height changing.
1287        mLastFrame.set(mFrame);
1288
1289        if (mContentInsetsChanged
1290                || mVisibleInsetsChanged
1291                || mStableInsetsChanged
1292                || winAnimator.mSurfaceResized
1293                || mOutsetsChanged
1294                || mFrameSizeChanged
1295                || mDisplayCutoutChanged
1296                || configChanged
1297                || dragResizingChanged
1298                || mReportOrientationChanged) {
1299            if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
1300                Slog.v(TAG_WM, "Resize reasons for w=" + this + ": "
1301                        + " contentInsetsChanged=" + mContentInsetsChanged
1302                        + " " + mContentInsets.toShortString()
1303                        + " visibleInsetsChanged=" + mVisibleInsetsChanged
1304                        + " " + mVisibleInsets.toShortString()
1305                        + " stableInsetsChanged=" + mStableInsetsChanged
1306                        + " " + mStableInsets.toShortString()
1307                        + " outsetsChanged=" + mOutsetsChanged
1308                        + " " + mOutsets.toShortString()
1309                        + " surfaceResized=" + winAnimator.mSurfaceResized
1310                        + " configChanged=" + configChanged
1311                        + " dragResizingChanged=" + dragResizingChanged
1312                        + " reportOrientationChanged=" + mReportOrientationChanged
1313                        + " displayCutoutChanged=" + mDisplayCutoutChanged);
1314            }
1315
1316            // If it's a dead window left on screen, and the configuration changed, there is nothing
1317            // we can do about it. Remove the window now.
1318            if (mAppToken != null && mAppDied) {
1319                mAppToken.removeDeadWindows();
1320                return;
1321            }
1322
1323            updateLastInsetValues();
1324            mService.makeWindowFreezingScreenIfNeededLocked(this);
1325
1326            // If the orientation is changing, or we're starting or ending a drag resizing action,
1327            // then we need to hold off on unfreezing the display until this window has been
1328            // redrawn; to do that, we need to go through the process of getting informed by the
1329            // application when it has finished drawing.
1330            if (getOrientationChanging() || dragResizingChanged) {
1331                if (DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
1332                    Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
1333                            + ", mDrawState=DRAW_PENDING in " + this
1334                            + ", surfaceController " + winAnimator.mSurfaceController);
1335                }
1336                winAnimator.mDrawState = DRAW_PENDING;
1337                if (mAppToken != null) {
1338                    mAppToken.clearAllDrawn();
1339                }
1340            }
1341            if (!mService.mResizingWindows.contains(this)) {
1342                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
1343                mService.mResizingWindows.add(this);
1344            }
1345        } else if (getOrientationChanging()) {
1346            if (isDrawnLw()) {
1347                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
1348                        + this + ", surfaceController " + winAnimator.mSurfaceController);
1349                setOrientationChanging(false);
1350                mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
1351                        - mService.mDisplayFreezeTime);
1352            }
1353        }
1354    }

28.wms->makewindowfreezingscreenifneededlocked

5591    void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
5592        // If the screen is currently frozen or off, then keep
5593        // it frozen/off until this window draws at its new
5594        // orientation.
5595        if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
5596            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
5597            w.setOrientationChanging(true);
5598            w.mLastFreezeDuration = 0;
5599            mRoot.mOrientationChangeComplete = false;
5600            if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
5601                mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
5602                // XXX should probably keep timeout from
5603                // when we first froze the display.
5604                mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5605                mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
5606                        WINDOW_FREEZE_TIMEOUT_DURATION);
5607            }
5608        }
5609    }

然后让我们回到24,在forallwindows后,需要进行preparesurface操作

29.displaycontent->preparesurfaces

4010    @Override
4011    void prepareSurfaces() {
4012        final ScreenRotationAnimation screenRotationAnimation =
4013                mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
4014        if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
4015            screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
4016            mPendingTransaction.setMatrix(mWindowingLayer,
4017                    mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
4018                    mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
4019            mPendingTransaction.setPosition(mWindowingLayer,
4020                    mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
4021            mPendingTransaction.setAlpha(mWindowingLayer,
4022                    screenRotationAnimation.getEnterTransformation().getAlpha());
4023        }
4024
4025        super.prepareSurfaces();
4026    }

30.super(windowcontainer)->preparesurfaces

1081    void prepareSurfaces() {
1082        SurfaceControl.mergeToGlobalTransaction(getPendingTransaction());
1083
1084        // If a leash has been set when the transaction was committed, then the leash reparent has
1085        // been committed.
1086        mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
1087        for (int i = 0; i < mChildren.size(); i++) {
1088            mChildren.get(i).prepareSurfaces();
1089        }
1090    }

31.taskstack->preparesurfaces

其实此处就是一层一层的遍历,直到找到最后的child,再进行preparesurfacelocked操作

1806    void prepareSurfaces() {
1807        mDimmer.resetDimStates();
1808        super.prepareSurfaces();
1809        getDimBounds(mTmpDimBoundsRect);
1810
1811        // Bounds need to be relative, as the dim layer is a child.
1812        mTmpDimBoundsRect.offsetTo(0, 0);
1813        if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
1814            scheduleAnimation();
1815        }
1816    }

32.windowstateanimator->preparesurfacelocked

1097    void prepareSurfaceLocked(final boolean recoveringMemory) {
1098        final WindowState w = mWin;
1099        if (!hasSurface()) {
1100
1101            // There is no need to wait for an animation change if our window is gone for layout
1102            // already as we'll never be visible.
1103            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1104                if (DEBUG_ORIENTATION) {
1105                    Slog.v(TAG, "Orientation change skips hidden " + w);
1106                }
1107                w.setOrientationChanging(false);
1108            }
1109            return;
1110        }
1111
1112        boolean displayed = false;
1113
1114        computeShownFrameLocked();
1115
1116        setSurfaceBoundariesLocked(recoveringMemory);
1117
1118        if (mIsWallpaper && !w.mWallpaperVisible) {
1119            // Wallpaper is no longer visible and there is no wp target => hide it.
1120            hide("prepareSurfaceLocked");
1121        } else if (w.isParentWindowHidden() || !w.isOnScreen()) {
1122            hide("prepareSurfaceLocked");
1123            mWallpaperControllerLocked.hideWallpapers(w);
1124
1125            // If we are waiting for this window to handle an orientation change. If this window is
1126            // really hidden (gone for layout), there is no point in still waiting for it.
1127            // Note that this does introduce a potential glitch if the window becomes unhidden
1128            // before it has drawn for the new orientation.
1129            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1130                w.setOrientationChanging(false);
1131                if (DEBUG_ORIENTATION) Slog.v(TAG,
1132                        "Orientation change skips hidden " + w);
1133            }
1134        } else if (mLastLayer != mAnimLayer
1135                || mLastAlpha != mShownAlpha
1136                || mLastDsDx != mDsDx
1137                || mLastDtDx != mDtDx
1138                || mLastDsDy != mDsDy
1139                || mLastDtDy != mDtDy
1140                || w.mLastHScale != w.mHScale
1141                || w.mLastVScale != w.mVScale
1142                || mLastHidden) {
1143            displayed = true;
1144            mLastAlpha = mShownAlpha;
1145            mLastLayer = mAnimLayer;
1146            mLastDsDx = mDsDx;
1147            mLastDtDx = mDtDx;
1148            mLastDsDy = mDsDy;
1149            mLastDtDy = mDtDy;
1150            w.mLastHScale = w.mHScale;
1151            w.mLastVScale = w.mVScale;
1152            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1153                    "controller=" + mSurfaceController +
1154                    "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1155                    + " matrix=[" + mDsDx + "*" + w.mHScale
1156                    + "," + mDtDx + "*" + w.mVScale
1157                    + "][" + mDtDy + "*" + w.mHScale
1158                    + "," + mDsDy + "*" + w.mVScale + "]", false);
1159
1160            boolean prepared =
1161                mSurfaceController.prepareToShowInTransaction(mShownAlpha,
1162                        mDsDx * w.mHScale * mExtraHScale,
1163                        mDtDx * w.mVScale * mExtraVScale,
1164                        mDtDy * w.mHScale * mExtraHScale,
1165                        mDsDy * w.mVScale * mExtraVScale,
1166                        recoveringMemory);
1167
1168            if (prepared && mDrawState == HAS_DRAWN) {
1169                if (mLastHidden) {
1170                    if (showSurfaceRobustlyLocked()) {
1171                        markPreservedSurfaceForDestroy();
1172                        mAnimator.requestRemovalOfReplacedWindows(w);
1173                        mLastHidden = false;
1174                        if (mIsWallpaper) {
1175                            w.dispatchWallpaperVisibility(true);
1176                        }
1177                        // This draw means the difference between unique content and mirroring.
1178                        // Run another pass through performLayout to set mHasContent in the
1179                        // LogicalDisplay.
1180                        mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1181                                FINISH_LAYOUT_REDO_ANIM);
1182                        if (DEBUG_LAYOUT_REPEATS) {
1183                            mService.mWindowPlacerLocked.debugLayoutRepeats(
1184                                    "showSurfaceRobustlyLocked " + w,
1185                                    mAnimator.getPendingLayoutChanges(w.getDisplayId()));
1186                        }
1187                    } else {
1188                        w.setOrientationChanging(false);
1189                    }
1190                }
1191            }
1192            if (hasSurface()) {
1193                w.mToken.hasVisible = true;
1194            }
1195        } else {
1196            if (DEBUG_ANIM && isAnimationSet()) {
1197                Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
1198            }
1199            displayed = true;
1200        }
1201
1202        if (w.getOrientationChanging()) {
1203            if (!w.isDrawnLw()) {
1204                mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1205                mAnimator.mLastWindowFreezeSource = w;
1206                if (DEBUG_ORIENTATION) Slog.v(TAG,
1207                        "Orientation continue waiting for draw in " + w);
1208            } else {
1209                w.setOrientationChanging(false);
1210                if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
1211            }
1212        }
1213
1214        if (displayed) {
1215            w.mToken.hasVisible = true;
1216        }
1217    }

33.rootwindowcontainer->reportresized

让我们回到23处接着往下看

871    private ArraySet<DisplayContent> handleResizingWindows() {
872        ArraySet<DisplayContent> touchExcludeRegionUpdateSet = null;
873        for (int i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
874            WindowState win = mService.mResizingWindows.get(i);
875            if (win.mAppFreezing) {
876                // Don't remove this window until rotation has completed.
877                continue;
878            }
879            win.reportResized();
880            mService.mResizingWindows.remove(i);
881            if (WindowManagerService.excludeWindowTypeFromTapOutTask(win.mAttrs.type)) {
882                final DisplayContent dc = win.getDisplayContent();
883                if (touchExcludeRegionUpdateSet == null) {
884                    touchExcludeRegionUpdateSet = new ArraySet<>();
885                }
886                touchExcludeRegionUpdateSet.add(dc);
887            }
888        }
889        return touchExcludeRegionUpdateSet;
890    }

34.windowstate->reportresized

2976    void reportResized() {
2977        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
2978        try {
2979            if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
2980                    + ": " + mCompatFrame);
2981            final MergedConfiguration mergedConfiguration =
2982                    new MergedConfiguration(mService.mRoot.getConfiguration(),
2983                    getMergedOverrideConfiguration());
2984
2985            setLastReportedMergedConfiguration(mergedConfiguration);
2986
2987            if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
2988                Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
2989
2990            final Rect frame = mFrame;
2991            final Rect overscanInsets = mLastOverscanInsets;
2992            final Rect contentInsets = mLastContentInsets;
2993            final Rect visibleInsets = mLastVisibleInsets;
2994            final Rect stableInsets = mLastStableInsets;
2995            final Rect outsets = mLastOutsets;
2996            final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING;
2997            final boolean reportOrientation = mReportOrientationChanged;
2998            final int displayId = getDisplayId();
2999            final DisplayCutout displayCutout = mDisplayCutout.getDisplayCutout();
3000            if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
3001                    && mClient instanceof IWindow.Stub) {
3002                // To prevent deadlock simulate one-way call if win.mClient is a local object.
3003                mService.mH.post(new Runnable() {
3004                    @Override
3005                    public void run() {
3006                        try {
3007                            dispatchResized(frame, overscanInsets, contentInsets, visibleInsets,
3008                                    stableInsets, outsets, reportDraw, mergedConfiguration,
3009                                    reportOrientation, displayId, displayCutout);
3010                        } catch (RemoteException e) {
3011                            // Not a remote call, RemoteException won't be raised.
3012                        }
3013                    }
3014                });
3015            } else {
3016                dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
3017                        outsets, reportDraw, mergedConfiguration, reportOrientation, displayId,
3018                        displayCutout);
3019            }
3020
3021            //TODO (multidisplay): Accessibility supported only for the default display.
3022            if (mService.mAccessibilityController != null && getDisplayId() == DEFAULT_DISPLAY) {
3023                mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
3024            }
3025
3026            mOverscanInsetsChanged = false;
3027            mContentInsetsChanged = false;
3028            mVisibleInsetsChanged = false;
3029            mStableInsetsChanged = false;
3030            mOutsetsChanged = false;
3031            mFrameSizeChanged = false;
3032            mDisplayCutoutChanged = false;
3033            mWinAnimator.mSurfaceResized = false;
3034            mReportOrientationChanged = false;
3035        } catch (RemoteException e) {
3036            setOrientationChanging(false);
3037            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
3038                    - mService.mDisplayFreezeTime);
3039            // We are assuming the hosting process is dead or in a zombie state.
3040            Slog.w(TAG, "Failed to report 'resized' to the client of " + this
3041                    + ", removing this window.");
3042            mService.mPendingRemove.add(this);
3043            mService.mWindowPlacerLocked.requestTraversal();
3044        }
3045        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3046    }

那么进行绘制之后就需要结束了

35.windowstateanimator->finishdrawinglocked

329    boolean finishDrawingLocked() {
330        final boolean startingWindow =
331                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
332        if (DEBUG_STARTING_WINDOW && startingWindow) {
333            Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
334                    + drawStateToString());
335        }
336
337        boolean layoutNeeded = false;
338
339        if (mDrawState == DRAW_PENDING) {
340            if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
341                Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
342                        + mSurfaceController);
343            if (DEBUG_STARTING_WINDOW && startingWindow) {
344                Slog.v(TAG, "Draw state now committed in " + mWin);
345            }
346            mDrawState = COMMIT_DRAW_PENDING;
347            layoutNeeded = true;
348        }
349
350        return layoutNeeded;
351    }

让我们回到22处继续往下看,在完成了绘制之后,就需要stopfreezing。

####36.wms->stopfreezingdisplaylocked

5900    void stopFreezingDisplayLocked() {
5901        if (!mDisplayFrozen) {
5902            return;
5903        }
5904
5905        if (mWaitingForConfig || mAppsFreezingScreen > 0
5906                || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
5907                || mClientFreezingScreen || !mOpeningApps.isEmpty()) {
5908            if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
5909                "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
5910                + ", mAppsFreezingScreen=" + mAppsFreezingScreen
5911                + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
5912                + ", mClientFreezingScreen=" + mClientFreezingScreen
5913                + ", mOpeningApps.size()=" + mOpeningApps.size());
5914            return;
5915        }
5916
5917        if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
5918                "stopFreezingDisplayLocked: Unfreezing now");
5919
5920        final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId);
5921
5922        // We must make a local copy of the displayId as it can be potentially overwritten later on
5923        // in this method. For example, {@link startFreezingDisplayLocked} may be called as a result
5924        // of update rotation, but we reference the frozen display after that call in this method.
5925        final int displayId = mFrozenDisplayId;
5926        mFrozenDisplayId = INVALID_DISPLAY;
5927        mDisplayFrozen = false;
5928        mInputMonitor.thawInputDispatchingLw();
5929        mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
5930        StringBuilder sb = new StringBuilder(128);
5931        sb.append("Screen frozen for ");
5932        TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
5933        if (mLastFinishedFreezeSource != null) {
5934            sb.append(" due to ");
5935            sb.append(mLastFinishedFreezeSource);
5936        }
5937        Slog.i(TAG_WM, sb.toString());
5938        mH.removeMessages(H.APP_FREEZE_TIMEOUT);
5939        mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
5940        if (PROFILE_ORIENTATION) {
5941            Debug.stopMethodTracing();
5942        }
5943
5944        boolean updateRotation = false;
5945
5946        ScreenRotationAnimation screenRotationAnimation =
5947                mAnimator.getScreenRotationAnimationLocked(displayId);
5948        if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
5949                && screenRotationAnimation.hasScreenshot()) {
5950            if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation");
5951            // TODO(multidisplay): rotation on main screen only.
5952            DisplayInfo displayInfo = displayContent.getDisplayInfo();
5953            // Get rotation animation again, with new top window
5954            if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, false)) {
5955                mExitAnimId = mEnterAnimId = 0;
5956            }
5957            if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION,
5958                    getTransitionAnimationScaleLocked(), displayInfo.logicalWidth,
5959                        displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
5960                mTransaction.apply();
5961                scheduleAnimationLocked();//发送动画
5962            } else {
5963                screenRotationAnimation.kill();
5964                mAnimator.setScreenRotationAnimationLocked(displayId, null);
5965                updateRotation = true;
5966            }
5967        } else {
5968            if (screenRotationAnimation != null) {
5969                screenRotationAnimation.kill();
5970                mAnimator.setScreenRotationAnimationLocked(displayId, null);
5971            }
5972            updateRotation = true;
5973        }
5974
5975        boolean configChanged;
5976
5977        // While the display is frozen we don't re-compute the orientation
5978        // to avoid inconsistent states.  However, something interesting
5979        // could have actually changed during that time so re-evaluate it
5980        // now to catch that.
5981        configChanged = updateOrientationFromAppTokensLocked(displayId);
5982
5983        // A little kludge: a lot could have happened while the
5984        // display was frozen, so now that we are coming back we
5985        // do a gc so that any remote references the system
5986        // processes holds on others can be released if they are
5987        // no longer needed.
5988        mH.removeMessages(H.FORCE_GC);
5989        mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
5990
5991        mScreenFrozenLock.release();
5992
5993        if (updateRotation) {
5994            if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation");
5995            configChanged |= displayContent.updateRotationUnchecked();
5996        }
5997
5998        if (configChanged) {
5999            mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
6000        }
6001        mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
6002        if (mPerf != null) {
6003            mPerf.perfLockRelease();
6004        }
6005    }

在stop之后就需要运行在startfreezing时候设置的转屏动画

37.windowanimator->scheduleanimation

392    void scheduleAnimation() {
393        if (!mAnimationFrameCallbackScheduled) {
394            mAnimationFrameCallbackScheduled = true;
395            mChoreographer.postFrameCallback(mAnimationFrameCallback);
396        }
397    }

这里的动画就不多做解释了。

####38.最后会发送消息SEND_NEW_CONFIGURATION来出发ams的configuration改变的功能。

>