packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
private void updateIsEnabled() {
boolean isEnabled = mIsAttached && mIsGesturalModeEnabled;
if (isEnabled == mIsEnabled) {
return;
}
mIsEnabled = isEnabled;
disposeInputChannel();
if (mEdgeBackPlugin != null) {
mEdgeBackPlugin.onDestroy();
mEdgeBackPlugin = null;
}
if (!mIsEnabled) {
mGestureNavigationSettingsObserver.unregister();
if (DEBUG_MISSING_GESTURE) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "Unregister display listener");
}
mPluginManager.removePluginListener(this);
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
mPipOptional.ifPresent(pip -> pip.setOnIsInPipStateChangedListener(null));
try {
mWindowManagerService.unregisterSystemGestureExclusionListener(
mGestureExclusionListener, mDisplayId);
} catch (RemoteException | IllegalArgumentException e) {
Log.e(TAG, "Failed to unregister window manager callbacks", e);
}
} else {
mGestureNavigationSettingsObserver.register();
updateDisplaySize();
if (DEBUG_MISSING_GESTURE) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "Register display listener");
}
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
mMainExecutor::execute, mOnPropertiesChangedListener);
mPipOptional.ifPresent(
pip -> pip.setOnIsInPipStateChangedListener(mOnIsInPipStateChangedListener));
try {
mWindowManagerService.registerSystemGestureExclusionListener(
mGestureExclusionListener, mDisplayId);
} catch (RemoteException | IllegalArgumentException e) {
Log.e(TAG, "Failed to register window manager callbacks", e);
}
// Register input event receiver
// 新建一个mInputMonitor 通过 monitorGestureInput
mInputMonitor = InputManager.getInstance().monitorGestureInput(
"edge-swipe", mDisplayId);
// 封装成 InputEventReceiver 对于收到的事件将在 InputEventReceiver 里面实现
mInputEventReceiver = new InputChannelCompat.InputEventReceiver(
mInputMonitor.getInputChannel(), Looper.getMainLooper(),
Choreographer.getInstance(), this::onInputEvent);
// Add a nav bar panel window
mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
resetEdgeBackPlugin();
mPluginManager.addPluginListener(
this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
}
// Update the ML model resources.
updateMLModelState();
}
services/core/java/com/android/server/input/InputManagerService.java
public InputMonitor monitorGestureInput(IBinder monitorToken, @NonNull String requestedName,
int displayId) {
if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
"monitorGestureInput()")) {
throw new SecurityException("Requires MONITOR_INPUT permission");
}
Objects.requireNonNull(requestedName, "name must not be null.");
Objects.requireNonNull(monitorToken, "token must not be null.");
if (displayId < Display.DEFAULT_DISPLAY) {
throw new IllegalArgumentException("displayId must >= 0.");
}
// 命名为 Gesture Monitor ***
final String name = "[Gesture Monitor] " + requestedName;
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
// 通过 createSpyWindowGestureMonitor创建 InputChannel
final InputChannel inputChannel =
createSpyWindowGestureMonitor(monitorToken, name, displayId, pid, uid);
// 构造 InputMonitor
return new InputMonitor(inputChannel, new InputMonitorHost(inputChannel.getToken()));
} finally {
Binder.restoreCallingIdentity(ident);
}
}
services/core/java/com/android/server/input/InputManagerService.java
private InputChannel createSpyWindowGestureMonitor(IBinder monitorToken, String name,
int displayId, int pid, int uid) {
// 新建sc 在sf建立一个对应的surfac
final SurfaceControl sc = mWindowManagerCallbacks.createSurfaceForGestureMonitor(name,
displayId);
if (sc == null) {
throw new IllegalArgumentException(
"Could not create gesture monitor surface on display: " + displayId);
}
// 新建一个InputChannel
final InputChannel channel = createInputChannel(name);
try {
monitorToken.linkToDeath(() -> removeSpyWindowGestureMonitor(channel.getToken()), 0);
} catch (RemoteException e) {
Slog.i(TAG, "Client died before '" + name + "' could be created.");
return null;
}
synchronized (mInputMonitors) {
mInputMonitors.put(channel.getToken(),
// 新建一个 GestureMonitorSpyWindow 重要
new GestureMonitorSpyWindow(monitorToken, name, displayId, pid, uid, sc,
channel));
}
final InputChannel outInputChannel = new InputChannel();
channel.copyTo(outInputChannel);
return outInputChannel;
}
services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
GestureMonitorSpyWindow(IBinder token, String name, int displayId, int pid, int uid,
SurfaceControl sc, InputChannel inputChannel) {
mMonitorToken = token;
mClientChannel = inputChannel;
mInputSurface = sc;
// 居然还专门构造了一个 ApplicationHandle
mApplicationHandle = new InputApplicationHandle(null, name,
DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
// 新建 WindowHandle
mWindowHandle = new InputWindowHandle(mApplicationHandle, displayId);
mWindowHandle.name = name;
mWindowHandle.token = mClientChannel.getToken();
// 添加一些窗口标记
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
mWindowHandle.ownerPid = pid;
mWindowHandle.ownerUid = uid;
mWindowHandle.scaleFactor = 1.0f;
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
// 重要的inputConfig 最重要的是 InputConfig.SPY 后面分析
mWindowHandle.inputConfig =
InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
// 把sc的信息,连同mWindowHandle 信息传给 sf, 后续该信息将会同步到 inputflinger
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setInputWindowInfo(mInputSurface, mWindowHandle);
// 注意 设置层级 为最高
t.setLayer(mInputSurface, Integer.MAX_VALUE);
t.setPosition(mInputSurface, 0, 0);
t.setCrop(mInputSurface, null /* crop to parent surface */);
t.show(mInputSurface);
t.apply();
}
接下来到 InputDispatcher.cpp
dispatcher/InputDispatcher.cpp
InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
ATRACE_CALL();
// 去寻找对应的窗口, 能找到的话 ,就只能找到一个 找的是非Spy类型的窗口
newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
isStylus, isDown /*addOutsideTargets*/);
........
// 找的是 Spy 类型的窗口 ,就是 之前添加的estureMonitorSpyWindow
std::vector<sp<WindowInfoHandle>> newTouchedWindows =
findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
.......
return injectionResult;
}
std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
// Traverse windows from front to back and gather the touched spy windows.
std::vector<sp<WindowInfoHandle>> spyWindows;
const auto& windowHandles = getWindowHandlesLocked(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
const WindowInfo& info = *windowHandle->getInfo();
if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
continue;
}
if (!info.isSpy()) {
// The first touched non-spy window was found, so return the spy windows touched so far.
return spyWindows;
}
// 从上到下,遍历所有windowHandle,找出所有Spy类型的windowHandle,并返回
spyWindows.push_back(windowHandle);
}
return spyWindows;
}