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

// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
// 进入RootWindowContainer中
boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows);
return changed;
}

其中,第一个参数表示更新焦点窗口时所处的阶段,共有五个参数:

// 表示正常更新
static final int UPDATE_FOCUS_NORMAL = 0;
// 表示此次更新焦点窗口发生在window layer分配之前
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
// 表示此次更新焦点窗口发生在进行放置Surface过程中,在performSurfacePlacement()时
static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
// 表示此次更新焦点窗口发生在进行放置Surface之前
static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
// 表示此次更新焦点窗口发生在焦点窗口移除后
static final int UPDATE_FOCUS_REMOVING_FOCUS = 4;

如在Window添加过程的WMS#addWindow()方法中,更新焦点窗口发生在分配窗口layer流程之前,因此使用UPDATE_FOCUS_WILL_ASSIGN_LAYERS作为第一个参数,表示此次更新时,还没有分配layer。 针对不同阶段,会有不同的操作。

第二个参数表示是否同步更新InputWindow。

1.2.RWC#updateFocusedWindowLocked()

WMS中发起更新焦点窗口后,由RootWindowContainer中处理:

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

boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
// 存储了当前焦点窗口的Pid和ActivityRecord的Map映射
mTopFocusedAppByProcess.clear();
boolean changed = false;
int topFocusedDisplayId = INVALID_DISPLAY;
// 遍历DisplayContent
for (int i = mChildren.size() - 1; i >= 0; --i) {
final DisplayContent dc = mChildren.get(i);
// 针对每个DisplayContent,进行焦点窗口更新
changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
// 更新全局焦点窗口
final WindowState newFocus = dc.mCurrentFocus;
if (newFocus != null) {
final int pidOfNewFocus = newFocus.mSession.mPid;
if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) {
mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord);
}
} else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
topFocusedDisplayId = dc.getDisplayId();
}
}
// 更新mTopFocusedDisplayId,表示焦点屏幕
if (mTopFocusedDisplayId != topFocusedDisplayId) {
mTopFocusedDisplayId = topFocusedDisplayId;
mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
}
return changed;
}

这里会遍历DisplayContent,并在每个DisplayContent中进行更新,然后将更新的结果返回给DisplayContent#mCurrentFocus变量,该变量表示全局的焦点窗口。同时更新mTopFocusedDisplayId变量,表示当前焦点屏(即焦点窗口所在的屏)。

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;
// 更新IM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值