1.3.DisplayContent#updateFocusedWindowLocked()
该方法如下:
// frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
int topFocusedDisplayId) {
// 寻找焦点窗口
WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
// 焦点窗口没有变化时,返回false
if (mCurrentFocus == newFocus) {
return false;
}
boolean imWindowChanged = false;
final WindowState imWindow = mInputMethodWindow;
// 更新IME target窗口
if (imWindow != null) {
// 记录当前IME Target窗口
final WindowState prevTarget = mInputMethodTarget;
// 获取新的IME Target窗口
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 (m