一、强制设置方向
1.Activity
如果要强制设置一个Activity的横竖屏可以通过Manifest去设置,跟Activity相关的信息都会保存在ActivityInfo当中。
-
android:screenOrientation=["unspecified" | "user" | "behind" |
-
"landscape" | "portrait" |
-
"reverseLandscape" | "reversePortrait" |
-
"sensorLandscape" | "sensorPortrait" |
-
"sensor" | "fullSensor" | "nosensor"]
2.Window
如果是要强制设置一个Window的横竖屏可以通过 LayoutParams.screenOrientation来设置。在通过WindowManager.addView的时候把对应的LayoutParams传递给WMS。
WindowManager.LayoutParams.screenOrientation
二、屏幕转屏
2.1 Activity -- 启动一个有设置screenOrientation的Activity
在ActivityStack.startActivityLocked中,AMS会把ActivityRecord相关的Token加到WMS中,有且仅在这个方法中。这时候会把screenOrientation传递过去。
atoken.requestedOrientation = requestedOrientation; 这个AppToken会在WMS获取相关App Orientation的时候其作用。
-
mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,
-
r.task.taskId, r.info.screenOrientation, r.fullscreen,
-
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
-
public void addAppToken(int addPos, int userId, IApplicationToken token,
-
int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
-
... ...
-
synchronized(mWindowMap) {
-
AppWindowToken atoken = findAppWindowToken(token.asBinder());
-
if (atoken != null) {
-
Slog.w(TAG, "Attempted to add existing app token: " + token);
-
return;
-
}
-
atoken = new AppWindowToken(this, userId, token);
-
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
-
atoken.groupId = groupId;
-
atoken.appFullscreen = fullscreen;
-
atoken.showWhenLocked = showWhenLocked;
-
atoken.requestedOrientation = requestedOrientation;//方向赋值
-
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
-
+ " at " + addPos);
-
mAppTokens.add(addPos, atoken);
-
addAppTokenToAnimating(addPos, atoken);
-
mTokenMap.put(token.asBinder(), atoken);
-
-
// Application tokens start out hidden.
-
atoken.hidden = true;
-
atoken.hiddenRequested = true;
-
-
//dump();
-
}
-
}
2.2 在启动Activity之前去获取当前WMS中的Orientation的Config
在resumeTopActivityLocked和realStartActivityLocked中回去获取最新的Orientation的config
1. 通过mWindowManager.updateOrientationFromAppTokens去更新当前WMS中的Orientation值,把WMS中的config返回给AMS ,这个我们在之前http://blog.csdn.net/kc58236582/article/details/53741445博客分析过了
2. 通过updateConfigurationLocked去更新AMS中的config,发给每一个ActiviytThread。(会调用每个ActivityThread的onConfigurationChanged函数)
-
synchronized (mService) {
-
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
-
mService.mConfiguration,
-
next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
-
if (config != null) {
-
next.frozenBeforeDestroy = true;
-
}
-
updated = mService.updateConfigurationLocked(config, next, false, false);
-
}
WMS.updateOrientationFroemAppTokens 会直接去调updateOrientationFromAppTokensLocked
1. 去调用updateOrientationFromAppTokensLocked(false) 做真正的update Orientation的工作,如果返回是true,说明方向发生了变化,就需要去做app的转屏动作。
2. 如果freezeThisOneIfNeed不为null,说明要做屏幕的转屏操做,就会把当前的atoken freeze掉。
3. computeNewConfigurationLocked() 计算当前的Configuration,然后返回给AMS。
-
private Configuration updateOrientationFromAppTokensLocked(
-
Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
-
Configuration config = null;
-
-
if (updateOrientationFromAppTokensLocked(false)) {
-
if (freezeThisOneIfNeeded != null) {
-
AppWindowToken atoken = findAppWindowToken(
-
freezeThisOneIfNeeded);
-
if (atoken != null) {
-
startAppFreezingScreenLocked(atoken,
-
ActivityInfo.CONFIG_ORIENTATION);
-
}
-
}
-
config = computeNewConfigurationLocked();
-
-
} else if (currentConfig != null) {
-
// No obvious action we need to take, but if our current
-
// state mismatches the activity manager's, update it,
-
// disregarding font scale, which should remain set to
-
// the value of the previous configuration.
-
mTempConfiguration.setToDefaults();
-
mTempConfiguration.fontScale = currentConfig.fontScale;
-
if (computeScreenConfigurationLocked(mTempConfiguration)) {
-
if (currentConfig.diff(mTempConfiguration) != 0) {
-
mWaitingForConfig = true;
-
getDefaultDisplayContentLocked().layoutNeeded = true;
-
startFreezingDisplayLocked(false, 0, 0);
-
config = new Configuration(mTempConfiguration);
-
}
-
}
-
}
-
-
return config;
-
}
updateOrientationFromAppTokensLocked 会查找出当前是否有需要强制Orientation的App或者Window
1. computeForcedAppOrientationLocked //goto 3.2.1.1.1
2. 如果ForcedAppOrientation发生了变化, 就会去通知WindowPolicy去设置当前的Sensor的状态。//goto 3.2.1.1.2
3. updateRotationUncheckedLocked(inTransaction),由于Orientation可能发生变化,所以需要去重新获取一下Rotation;具体就可以参照前一节了。
如果Rotation发生了变化就返回true。跟configuration相关的东西,大多都在这个函数中进行。
-
boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
-
long ident = Binder.clearCallingIdentity();
-
try {
-
int req = computeForcedAppOrientationLocked();
-
-
if (req != mForcedAppOrientation) {
-
mForcedAppOrientation = req;
-
//send a message to Policy indicating orientation change to take
-
//action like disabling/enabling sensors etc.,
-
mPolicy.setCurrentOrientationLw(req);
-
if (updateRotationUncheckedLocked(inTransaction)) {
-
// changed
-
return true;
-
}
-
}
-
-
return false;
-
} finally {
-
Binder.restoreCallingIdentity(ident);
-
}
-
}
computeForcedAppOrientationLocked
这个函数的作用就是去查询当前即将要显示的Activity或者Window有没有需要强制Orientation的
1. 先通过 getOrientationFromWindowsLocked去遍历WMS中的WindowList。
1)如果在最上面的Window是一个AppWindow就直接返回mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
2)如果不是AppWindow,判断这个Window是否可见,如果不可见就continue
3)最后如果这个Window既不是AppWindow又要是可见的,并且他是有指定ScreenOrientation的,就返回这个window的orientatin。mLastWindowForcedOrientation=req
2. 如果getOrientationFromWindowsLocked找到的是一个AppWindow或者当前没有指定Orientation的Window,就会走到getOrientationFromAppTokensLocked();
1)这个函数会去遍历AppWindowToken List去查找需要强制Orientation的Token,这个时候就是根据我们之前在AMS中传递进来的atoken.requestedOrientation;来进行判断,如果设置了就返回回去给req。
-
int computeForcedAppOrientationLocked() {
-
int req = getOrientationFromWindowsLocked();
-
if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
-
req = getOrientationFromAppTokensLocked();
-
}
-
if (mForceLandScape &&
-
req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
-
req = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-
}
-
return req;
-
}
PhoneWindowManager.setCurrentOrientationLw()
1. 用mCurrentAppOrientation保存当前新的Orientation.
2. updateOrientationListenerLp,通过名字就知道他只是去管理是否启动Sensor Listener的。
-
public void setCurrentOrientationLw(int newOrientation) {
-
synchronized (mLock) {
-
if (newOrientation != mCurrentAppOrientation) {
-
mCurrentAppOrientation = newOrientation;
-
updateOrientationListenerLp();
-
}
-
}
-
}
WMS. computeNewConfiguration()
通过computeNewConfigurationLocked() 计算出一个新的configuration.随后就会在AMS中调用ActivityThread把这个数据最后传到应用进程
-
public Configuration computeNewConfiguration() {
-
synchronized (mWindowMap) {
-
Configuration config = computeNewConfigurationLocked();
-
if (config == null && mWaitingForConfig) {
-
// Nothing changed but we are waiting for something... stop that!
-
mWaitingForConfig = false;
-
performLayoutAndPlaceSurfacesLocked();
-
}
-
return config;
-
}
-
}
2.3 AMS端的工作完成之后,就到ActivityThread和ViewRootImpl的工作了
2.3.1 在ActivityThread的handleResume的时候会把Activity对应的DectorView加到WMS中,在WMS中会调用addWindow.
如果我们自己添加一个Window的话也是走到这边。 在AddWindow的时候有可能对Orietation和Configuration, 前提是这个win的isVisibleOrAdding的条件。不过一般都不会满足这个条件。
sendNewConfiguration最后会到AMS的updateConfiguration函数然后调用updateConfigurationLocked函数之前博客分析过了。
-
if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
-
reportNewConfig = true;
-
}
-
}
-
-
if (reportNewConfig) {
-
sendNewConfiguration();
-
}
2.3.2 当addWindow完成之后,ViewRootImpl就会去requestLayout,而requestLayout实际上就是去做scheduleTraversals
1. 在performTraversals中会先去做一次measureHierarchy计算一下View所需的大小。
2. 然后会调用relayoutWindow去请求WMS帮助实际计算当前Window的布局,创建一个Surface,并且返回对应的Frame。
2.3.4 WMS.relayoutWindow()
1. 根据传进来的requestWidth和requestHeight 或者attrChange的变化来决定是不是真的要relayout,并且把win.mLayoutNeeded设置为true。在performLayoutAndPlaceSurfacesLocked的会根据这个值做判断。
2. 如果当前的WindowState还没有Surface就调用 winAnimator.createSurfaceLocked();去创建一个Surface会带回给ViewRootImpl
3. 如果focus window发生变化了就updateFocusedWindowLocked
如果Layer变化了就调用assignLayersLocked
4. 再次调用updateOrientationFromAppTokensLocked去判断当前的Orietation是不是发生变化了。//在这个调用中如果有Orientation发生了变化,如果有变化就会调用computeNewConfigurationLocked()去更新DisplayContent相关的信息并且计算出一个新的Configuration
5. 调用performLayoutAndPlaceSurfacesLocked
6. 把WindowState中的三个Frame返回给Client端。
-
public int relayoutWindow(Session session, IWindow client, int seq,
-
WindowManager.LayoutParams attrs, int requestedWidth,
-
int requestedHeight, int viewVisibility, int flags,
-
Rect outFrame, Rect outContentInsets,
-
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
-
boolean toBeDisplayed = false;
-
boolean inTouchMode;
-
boolean configChanged;
-
boolean surfaceChanged = false;
-
boolean animating;
-
... ...
-
synchronized(mWindowMap) {
-
// TODO(cmautner): synchronize on mAnimator or win.mWinAnimator.
-
WindowState win = windowForClientLocked(session, client, false);
-
... ...
-
WindowStateAnimator winAnimator = win.mWinAnimator;
-
if (win.mRequestedWidth != requestedWidth
-
|| win.mRequestedHeight != requestedHeight) {
-
win.mLayoutNeeded = true;
-
win.mRequestedWidth = requestedWidth;
-
win.mRequestedHeight = requestedHeight;
-
}
-
if (attrs != null && seq == win.mSeq) {
-
win.mSystemUiVisibility = systemUiVisibility;
-
}
-
-
if (attrs != null) {
-
mPolicy.adjustWindowParamsLw(attrs);
-
}
-
-
winAnimator.mSurfaceDestroyDeferred =
-
(flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
-
-
int attrChanges = 0;
-
int flagChanges = 0;
-
if (attrs != null) {
-
-
flagChanges = win.mAttrs.flags ^= attrs.flags;
-
attrChanges = win.mAttrs.copyFrom(attrs);
-
if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
-
| WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
-
win.mLayoutNeeded = true;
-
}
-
}
-
... ...
-
if (viewVisibility == View.VISIBLE &&
-
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
-
toBeDisplayed = !win.isVisibleLw();
-
-
-
if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
-
// To change the format, we need to re-build the surface.
-
winAnimator.destroySurfaceLocked(false);
-
toBeDisplayed = true;
-
surfaceChanged = true;
-
}
-
try {
-
if (!win.mHasSurface) {
-
surfaceChanged = true;
-
}
-
Surface surface = winAnimator.createSurfaceLocked();
-
if (surface != null) {
-
outSurface.copyFrom(surface);
-
if (SHOW_TRANSACTIONS) Slog.i(TAG,
-
" OUT SURFACE " + outSurface + ": copied");
-
} else {
-
// For some reason there isn't a surface. Clear the
-
// caller's object so they see the same state.
-
outSurface.release();
-
}
-
} catch (Exception e) {
-
-
}
-
if (toBeDisplayed) {
-
focusMayChange = isDefaultDisplay;
-
}
-
if (win.mAttrs.type == TYPE_INPUT_METHOD
-
&& mInputMethodWindow == null) {
-
mInputMethodWindow = win;
-
imMayMove = true;
-
}
-
if (win.mAttrs.type == TYPE_BASE_APPLICATION
-
&& win.mAppToken != null
-
&& win.mAppToken.startingWindow != null) {
-
// Special handling of starting window over the base
-
// window of the app: propagate lock screen flags to it,
-
// to provide the correct semantics while starting.
-
final int mask =
-
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
-
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
-
WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
-
sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
-
}
-
} else {
-
winAnimator.mEnterAnimationPending = false;
-
if (winAnimator.mSurface != null) {
-
if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
-
+ ": mExiting=" + win.mExiting);
-
// If we are not currently running the exit animation, we
-
// need to see about starting one.
-
if (!win.mExiting) {
-
surfaceChanged = true;
-
// Try starting an animation; if there isn't one, we
-
// can destroy the surface right away.
-
int transit = WindowManagerPolicy.TRANSIT_EXIT;
-
if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
-
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
-
}
-
if (win.isWinVisibleLw() &&
-
winAnimator.applyAnimationLocked(transit, false)) {
-
focusMayChange = isDefaultDisplay;
-
win.mExiting = true;
-
} else if (win.mWinAnimator.isAnimating()) {
-
// Currently in a hide animation... turn this into
-
// an exit.
-
win.mExiting = true;
-
} else if (win == mWallpaperTarget) {
-
// If the wallpaper is currently behind this
-
// window, we need to change both of them inside
-
// of a transaction to avoid artifacts.
-
win.mExiting = true;
-
win.mWinAnimator.mAnimating = true;
-
} else {
-
if (mInputMethodWindow == win) {
-
mInputMethodWindow = null;
-
}
-
winAnimator.destroySurfaceLocked(false);
-
}
-
scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
-
}
-
}
-
-
outSurface.release();
-
if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
-
}
-
-
if (focusMayChange) {
-
//System.out.println("Focus may change: " + win.mAttrs.getTitle());
-
if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-
false /*updateInputWindows*/)) {
-
imMayMove = false;
-
}
-
//System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
-
}
-
-
// updateFocusedWindowLocked() already assigned layers so we only need to
-
// reassign them at this point if the IM window state gets shuffled
-
boolean assignLayers = false;
-
... ...
-
if (assignLayers) {
-
assignLayersLocked(win.getWindowList());
-
}
-
configChanged = updateOrientationFromAppTokensLocked(false);
-
performLayoutAndPlaceSurfacesLocked();
-
if (toBeDisplayed && win.mIsWallpaper) {
-
DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
-
updateWallpaperOffsetLocked(win,
-
displayInfo.appWidth, displayInfo.appHeight, false);
-
}
-
if (win.mAppToken != null) {
-
win.mAppToken.updateReportedVisibilityLocked();
-
}
-
outFrame.set(win.mCompatFrame);
-
outContentInsets.set(win.mContentInsets);
-
outVisibleInsets.set(win.mVisibleInsets);
-
... ...
-
-
mInputMonitor.updateInputWindowsLw(true /*force*/);
-
-
}
-
-
if (configChanged) {
-
sendNewConfiguration();
-
}
WMS.performLayoutAndPlaceSurfacesLockedLoop()
performLayoutAndPlaceSurfacesLocked直接去调performLayoutAndPlaceSurfacesLockedLoop, 在performLayoutAndPlaceSurfacesLockedLoop里面做两个最主要的操作。
1. performLayoutAndPlaceSurfacesLockedInner();
2. requestTraversalLocked();
-
private final void performLayoutAndPlaceSurfacesLockedLoop() {
-
... ...
-
-
mInLayout = true;
-
boolean recoveringMemory = false;
-
... ...
-
try {
-
performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-
-
mInLayout = false;
-
-
if (needsLayout()) {
-
if (++mLayoutRepeatCount < 6) {
-
requestTraversalLocked();
-
} else {
-
Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
-
mLayoutRepeatCount = 0;
-
}
-
} else {
-
mLayoutRepeatCount = 0;
-
}
-
-
if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
-
mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
-
mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
-
}
-
} catch (RuntimeException e) {
-
mInLayout = false;
-
Log.wtf(TAG, "Unhandled exception while laying out windows", e);
-
}
-
-
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
-
}
WMS.performLayoutAndPlaceSurfacesLockedInner(false)
1. 首先会获取当前的一个DsiplayContent,由于这个DisplayContent在updateOrientationFromAppTokensLocked的时候已经根据最新的window状态进行跟新过,所以现在的DsiplayContent应该是最新的值。
2. performLayoutLockedInner; 这个函数回去遍历每一个Window,然后根据当前的DisplayContent去更新Layout.
这个方法会根据最新的DisplayContent去判断所有的window是否需要重新layout
第一步,通过mPolicy.beginLayoutLw去给policy设置一个标准把当前的Content信息设置进去
第二步, mPolicy.layoutWindowLw(win, win.mAttrs, null); 给win做真正的layout,layout主要做了什么?有几个重要的变量?
在layoutWindow中会通过computeFrameLw去计算WindowState的中的Frame,有三个Frame;
3. updateResizingWindows(w);
如果WindowState其中的w.mContentInsetsChanged || w.mVisibleInsetsChanged || winAnimator.mSurfaceResized|| configChanged 任意的一个发生变化了就会加入到mResizingWindows数组中。并且把对应的Window Freezing。
4. 遍历mResizingWindows, 调用win.mClient.resized通过IPC告诉Clinet端要做resize
最终ViewRootImpl就会发送一个MSG_RESIZED去处理,WMS会把里面的三个Frame和Configuration发回给Clinet。ViewRoot会保存最新的三个Frame和updateConfiguration,最后 requestLayout();
-
private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
-
... ...
-
Surface.openTransaction();
-
try {
-
-
boolean focusDisplayed = false;
-
boolean updateAllDrawn = false;
-
-
DisplayContentsIterator iterator = new DisplayContentsIterator();
-
while (iterator.hasNext()) {
-
final DisplayContent displayContent = iterator.next();
-
WindowList windows = displayContent.getWindowList();
-
DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
final int displayId = displayContent.getDisplayId();
-
final int dw = displayInfo.logicalWidth;
-
final int dh = displayInfo.logicalHeight;
-
final int innerDw = displayInfo.appWidth;
-
final int innerDh = displayInfo.appHeight;
-
final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-
-
// Reset for each display unless we are forcing mirroring.
-
if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
-
mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
-
}
-
... ...
-
int repeats = 0;
-
do {
-
repeats++;
-
... ...
-
// FIRST LOOP: Perform a layout, if needed.
-
if (repeats < 4) {
-
performLayoutLockedInner(displayContent, repeats == 1,
-
false /*updateInputWindows*/);
-
} else {
-
Slog.w(TAG, "Layout repeat skipped after too many iterations");
-
}
-
... ...
-
} while (displayContent.pendingLayoutChanges != 0);
-
-
// Only used if default window
-
final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
-
-
final int N = windows.size();
-
for (i=N-1; i>=0; i--) {
-
WindowState w = windows.get(i);
-
... ...
-
-
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
-
w.mContentChanged = false;
-
-
// Moved from updateWindowsAndWallpaperLocked().
-
if (w.mHasSurface) {
-
// Take care of the window being ready to display.
-
... ...
-
}
-
... ...
-
}
-
}
-
-
if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
-
&& w.isDisplayedLw()) {
-
focusDisplayed = true;
-
}
-
-
updateResizingWindows(w);
-
}
-
-
... ...
-
-
for (i = mResizingWindows.size() - 1; i >= 0; i--) {
-
WindowState win = mResizingWindows.get(i);
-
if (win.mAppFreezing) {
-
// Don't remove this window until rotation has completed.
-
continue;
-
}
-
final WindowStateAnimator winAnimator = win.mWinAnimator;
-
try {
-
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
-
"Reporting new frame to " + win + ": " + win.mCompatFrame);
-
int diff = 0;
-
boolean configChanged = win.isConfigChanged();
-
if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
-
&& configChanged) {
-
Slog.i(TAG, "Sending new config to window " + win + ": "
-
+ winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
-
+ " / " + mCurConfiguration + " / 0x"
-
+ Integer.toHexString(diff));
-
}
-
win.setConfiguration(mCurConfiguration);
-
if (DEBUG_ORIENTATION &&
-
winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
-
TAG, "Resizing " + win + " WITH DRAW PENDING");
-
win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
-
winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
-
configChanged ? win.mConfiguration : null);
-
win.mContentInsetsChanged = false;
-
win.mVisibleInsetsChanged = false;
-
winAnimator.mSurfaceResized = false;
-
} catch (RemoteException e) {
-
win.mOrientationChanging = false;
-
}
-
mResizingWindows.remove(i);
-
}
-
-
... ...
-
-
// Finally update all input windows now that the window changes have stabilized.
-
mInputMonitor.updateInputWindowsLw(true /*force*/);
-
... ...
-
}
-
-
// Check to see if we are now in a state where the screen should
-
// be enabled, because the window obscured flags have changed.
-
enableScreenIfNeededLocked();
-
-
updateLayoutToAnimationLocked();
-
... ...
-
}