Android R WindowManagerService模块(5) 焦点窗口和InputWindows的更新

final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/);
// IME Target窗口是否发生变化
imWindowChanged = prevTarget != newTarget;
// 进行window layer的分配
if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
&& mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
assignWindowLayers(false /* setLayoutNeeded */);
}
}
// IME target窗口发生变化,重新获取一次焦点窗口
if (imWindowChanged) {
mWmService.mWindowsChanged = true;
setLayoutNeeded();
newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
}
// 通知WMS焦点窗口发生变化
if (mCurrentFocus != newFocus) {
mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
}
// 记录旧焦点窗口
final WindowState oldFocus = mCurrentFocus;
// 更新新焦点窗口
mCurrentFocus = newFocus;
// 从mLosingFocus移除
mLosingFocus.remove(newFocus);

if (newFocus != null) {
// 这俩列表用于记录ANR状态,表示自从焦点窗口为空时添加和移除的窗口
mWinAddedSinceNullFocus.clear();
mWinRemovedSinceNullFocus.clear();
// 设置焦点窗口所在mToken.paused属性为false
if (newFocus.canReceiveKeys()) {
newFocus.mToken.paused = false;
}
}
// 用于通知Task更新shadow radius
onWindowFocusChanged(oldFocus, newFocus);
// 通知DisplayPolicy焦点窗口发生变化,并接受返回结果
int focusChanged = getDisplayPolicy().focusChangedLw(oldFocus, newFocus);
// IME target窗口发生变化,且旧焦点窗口非输入法窗口时
if (imWindowChanged && oldFocus != mInputMethodWindow) {
// 根据mode, 进行layout或assign window layer操作
if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
performLayout(true /initial/, updateInputWindows);
focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
} else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
assignWindowLayers(false /* setLayoutNeeded */);
}
}
// DislayPolicy返回结果
if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
setLayoutNeeded();
if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
performLayout(true /initial/, updateInputWindows);
} else if (mode == UPDATE_FOCUS_REMOVING_FOCUS) {
mWmService.mRoot.performSurfacePlacement();
}
}
// 向InputMonitor中设置焦点窗口
if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
}
// 为IME窗口进行调整
adjustForImeIfNeeded();
// Toast窗口
scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);

if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
}
return true;
}

以上方法中:

    1. 通过findFocusedWindowIfNeeded()方法寻找焦点窗口;
    1. 根据焦点窗口的变化,更新Input Target窗口;
    1. 更新全局焦点窗口对象mCurrentFocus;
    1. 根据更新的不同阶段做不同处理。

下面看下如何寻找到焦点窗口。

1.4.DisplayContent#findFocusedWindowIfNeeded()

在这个方法中,会寻找到新的焦点窗口:

// frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
? findFocusedWindow() : null;
}

当topFocusedDisplayId为INVALID_DISPLAY时,认为当前焦点display没有焦点窗口,需要寻找重新确认,所以又继续执行findFocusedWindow()方法寻找:

// frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

WindowState findFocusedWindow() {
mTmpWindow = null;
// 遍历WindowState
forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);

if (mTmpWindow == null) {
return null;
}
return mTmpWindow;
}</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值