本文是对全局手势识别进行分析,那什么是全局手势呢?简单来说就是在任何界面都需要识别的手势,比如:在任何界面从手机屏幕左侧滑动,当前的界面会退出 (类似 back 键)。
我们知道,在 Android 系统中一个 Activity 在显示时,当对屏幕触摸事件进行响应时,经过了许多逻辑处理,详细分析可以参考之前对 IMS 原理分析的一系列文章: Android知识体系导图 中的输入系统章节。
接下来对全局手势事件注册监听及处理进行分析。目前使用 12.0 代码分析
RootWindowContainer 的构造是在 WindowManagerService 中:
WindowManagerService.java
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, DisplayWindowSettingsProvider
displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
Supplier<Surface> surfaceFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
……
mRoot = new RootWindowContainer(this);
……
}
可见 RootWindowContainer 对象作为 WindowManagerService 的成员变量 mRoot 存在。在 SystemServer 类的 startOtherServices 中,会调用 ActivityManagerService 的 setWindowManager() 方法:
SystemServer.java
mActivityManagerService.setWindowManager(wm);
ActivityManagerService.java
public void setWindowManager(WindowManagerService wm) {
1846 synchronized (this) {
1847 mWindowManager = wm;
1848 mWmInternal = LocalServices.getService(WindowManagerInternal.class);
1849 mActivityTaskManager.setWindowManager(wm);
1850 }
1851 }
进而调用 ActivityTaskManagerService 的 setWindowManager
ActivityTaskManagerService.java
public void setWindowManager(WindowManagerService wm) {
974 synchronized (mGlobalLock) {
975 mWindowManager = wm;
976 mRootWindowContainer = wm.mRoot;
977 mTempConfig.setToDefaults();
978 mTempConfig.setLocales(LocaleList.getDefault());
979 mConfigurationSeq = mTempConfig.seq = 1;
980 mRootWindowContainer.onConfigurationChanged(mTempConfig);
981 mLockTaskController.setWindowManager(wm);
982 mTaskSupervisor.setWindowManager(wm);
983 mRootWindowContainer.setWindowManager(wm);
984 }
985 }
ActivityTaskManagerService 的成员变量 mRootWindowContainer 也赋值为 RootWindowContainer 根对象。最后会调用RootWindowContainer的setWindowManager(wm)方法:
RootWindowContainer.java
void setWindowManager(WindowManagerService wm) {
1353 mWindowManager = wm;
1354 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
1355 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
1356 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
1357
1358 final Display[] displays = mDisplayManager.getDisplays();
1359 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
1360 final Display display = displays[displayNdx];
1361 final DisplayContent displayContent = new DisplayContent(display, this);
1362 addChild(displayContent, POSITION_BOTTOM);
1363 if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
1364 mDefaultDisplay = displayContent;
1365 }
1366 }
1367 calculateDefaultMinimalSizeOfResizeableTasks();
1368
1369 final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
1370 defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
1371 positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
1372 false /* includingParents */);
1373 }
从上面看出,通过屏幕管理对象 mDisplayManager 得到所有的显示屏幕,然后构造 DisplayContent 对象,再通过 addChild(displayContent, POSITION_BOTTOM) 方法将 DisplayContent 对象添加到 RootWindowContainer 根对象的树状结构中。
默认显示屏幕的 mDisplayId 是 DEFAULT_DISPLAY,看下它的值(Display类 public static final int DEFAULT_DISPLAY = 0),mDisplayId 为 0 作为基本显示屏幕。我们接下来看 DisplayContent 的构造函数。
在 DisplayContent.java 的构造函数中进行注册,代码如下:
DisplayContent.java
private final PointerEventDispatcher mPointerEventDispatcher;
DisplayContent(Display display, RootWindowContainer root) { // 构造函数中初始化
......
final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
1028 "PointerEventDispatcher" + mDisplayId, mDisplayId);
1029 mPointerEventDispatcher = new PointerEventDispatcher(inputChannel, this);
......
}
}
我们可以看到在 DisplayContent 的构造函数中,生成了 InputChannel,并作为参数传入 PointerEventDispatcher 中。我们知道这个 InputChannel 就是一对负责通信的 socket 通道。至于构建过程我们后面分析,我们只要知道它是 socket 通信通道的建立即可。
接着上面的分析,在 DisplayContent 的构造方法内部,通过 mWmService.mInputManager.monitorInput() 的返回值 InputChannel,创建了PointerEventDispatcher对象,一起看一下PointerEventDispatcher的实现:
public class PointerEventDispatcher extends InputEventReceiver {
35 private final ArrayList<PointerEventListener> mListeners = new ArrayList<>();
36 private PointerEventListener[] mListenersArray = new PointerEventListener[0];
37
38 private final DisplayContent mDisplayContent;
39 private final Point mTmpSize = new Point();
40
41 public PointerEventDispatcher(InputChannel inputChannel, DisplayContent dc) {
42 super(inputChannel, UiThread.getHandler().getLooper());
43 mDisplayContent = dc;
44 }
45
46 @Override
47 public void onInputEvent(InputEvent event) {
48 try {
49 if (event instanceof MotionEvent
50 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
51 MotionEvent motionEvent = (MotionEvent) event;
52 if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
53 final int rotation = mDisplayContent.getRotation();
54 if (rotation != Surface.ROTATION_0) {
55 mDisplayContent.getDisplay().getRealSize(mTmpSize);
56 motionEvent = MotionEvent.obtain(motionEvent);
57 motionEvent.transform(MotionEvent.createRotateMatrix(
58 rotation, mTmpSize.x, mTmpSize.y));
59 }
60 }
61 PointerEventListener[] listeners;
62 synchronized (mListeners) {
63 if (mListenersArray == null) {
64 mListenersArray = new PointerEventListener[mListeners.size()];
65 mListeners.toArray(mListenersArray);
66 }
67 listeners = mListenersArray;
68 }
69 for (int i = 0; i < listeners.length; ++i) {
70 listeners[i].onPointerEvent(motionEvent);
71 }
72 }
73 } finally {
74 finishInputEvent(event, false);
75 }
76 }
77
78
82 public void registerInputEventListener(PointerEventListener listener) {
83 synchronized (mListeners) {
84 if (mListeners.contains(listener)) {
85 throw new IllegalStateException("registerInputEventListener: trying to register" +
86 listener + " twice.");
87 }
88 mListeners.add(listener);
89 mListenersArray = null;
90 }
91 }
92
93
97 public void unregisterInputEventListener(PointerEventListener listener) {
98 synchronized (mListeners) {
99 if (!mListeners.contains(listener)) {
100 throw new IllegalStateException("registerInputEventListener: " + listener +
101 " not registered.");
102 }
103 mListeners.remove(listener);
104 mListenersArray = null;
105 }
106 }
107
108 ......
117 }
可以看到,PointerEventDispatcher 继承了 InputEventReceiver,即:触摸事件从 native 返回后会回调 InputEventReceiver 的dispatchInputEvent() 方法,接着调用其继承类即 PointerEventDispatcher 的 onInputEvent() 方法,在该方法内遍历了所有的 Listener 并回调 onPointerEvent() 方法,通过 registerInputEventListener() 来注册监听。
上面分析了在 DisplayContent 构造方法内部建立了对 native 的监听,即当有触摸事件产生时,会回调到 onInputEvent() 方法,最终再回调所有 PointerEventListener 的 onPointerEvent(),那么 PointerEventListener 就是全局手势的接收者,onPointerEvent() 就是对全局手势的处理方法。
先看一下 PointerEventListener,定义在 WindowManagerPolicyConstants.java 里面:
WindowManagerPolicyConstants.java
interface PointerEventListener {
108 /**
109 * 1. onPointerEvent will be called on the service.UiThread.
110 * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
111 * copy() must be made and the copy must be recycled.
112 **/
113 void onPointerEvent(MotionEvent motionEvent);
114 }
PointerEventListener 是一个接口,来看一下具体实现类,实现类为 SystemGesturesPointerEventListener:
SystemGesturesPointerEventListener.java
class SystemGesturesPointerEventListener implements PointerEventListener {
41 private static final String TAG = "SystemGestures";
42 private static final boolean DEBUG = false;
43 private static final long SWIPE_TIMEOUT_MS = 500;
44 private static final int MAX_TRACKED_POINTERS = 32; // max per input system
45 private static final int UNTRACKED_POINTER = -1;
46 private static final int MAX_FLING_TIME_MILLIS = 5000;
47
48 private static final int SWIPE_NONE = 0;
49 private static final int SWIPE_FROM_TOP = 1;
50 private static final int SWIPE_FROM_BOTTOM = 2;
51 private static final int SWIPE_FROM_RIGHT = 3;
52 private static final int SWIPE_FROM_LEFT = 4;
53
54 ......
64
65 private GestureDetector mGestureDetector;
66
67 ......
75
76 SystemGesturesPointerEventListener(Context context, Handler handler, Callbacks callbacks) {
77 mContext = checkNull("context", context);
78 mHandler = handler;
79 mCallbacks = checkNull("callbacks", callbacks);
80 onConfigurationChanged();
81 }
82
83 ......
120
121 public void systemReady() {
131 mHandler.post(() -> {
132 final int displayId = mContext.getDisplayId();
133 final DisplayInfo info = DisplayManagerGlobal.getInstance().getDisplayInfo(displayId);
134 if (info == null) {
135 // Display already removed, stop here.
136 Slog.w(TAG, "Cannot create GestureDetector, display removed:" + displayId);
137 return;
138 }
139 mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {
140 };
141 });
142 }
143
144 @Override
145 public void onPointerEvent(MotionEvent event) {
146 if (mGestureDetector != null && event.isTouchEvent()) {
147 mGestureDetector.onTouchEvent(event);
148 }
149 switch (event.getActionMasked()) {
150 case MotionEvent.ACTION_DOWN:
151 mSwipeFireable = true;
152 mDebugFireable = true;
153 mDownPointers = 0;
154 captureDown(event, 0);
155 if (mMouseHoveringAtEdge) {
156 mMouseHoveringAtEdge = false;
157 mCallbacks.onMouseLeaveFromEdge();
158 }
159 mCallbacks.onDown();
160 break;
161 case MotionEvent.ACTION_POINTER_DOWN:
162 captureDown(event, event.getActionIndex());
163 if (mDebugFireable) {
164 mDebugFireable = event.getPointerCount() < 5;
165 if (!mDebugFireable) {
166 if (DEBUG) Slog.d(TAG, "Firing debug");
167 mCallbacks.onDebug();
168 }
169 }
170 break;
171 case MotionEvent.ACTION_MOVE:
172 if (mSwipeFireable) {
173 final int swipe = detectSwipe(event);
174 mSwipeFireable = swipe == SWIPE_NONE;
175 if (swipe == SWIPE_FROM_TOP) {
176 if (DEBUG) Slog.d(TAG, "Firing onSwipeFromTop");
177 mCallbacks.onSwipeFromTop();
178 } else if (swipe == SWIPE_FROM_BOTTOM) {
179 if (DEBUG) Slog.d(TAG, "Firing onSwipeFromBottom");
180 mCallbacks.onSwipeFromBottom();
181 } else if (swipe == SWIPE_FROM_RIGHT) {
182 if (DEBUG) Slog.d(TAG, "Firing onSwipeFromRight");
183 mCallbacks.onSwipeFromRight();
184 } else if (swipe == SWIPE_FROM_LEFT) {
185 if (DEBUG) Slog.d(TAG, "Firing onSwipeFromLeft");
186 mCallbacks.onSwipeFromLeft();
187 }
188 }
189 break;
190 case MotionEvent.ACTION_HOVER_MOVE:
191 if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
192 if (!mMouseHoveringAtEdge && event.getY() == 0) {
193 mCallbacks.onMouseHoverAtTop();
194 mMouseHoveringAtEdge = true;
195 } else if (!mMouseHoveringAtEdge && event.getY() >= screenHeight - 1) {
196 mCallbacks.onMouseHoverAtBottom();
197 mMouseHoveringAtEdge = true;
198 } else if (mMouseHoveringAtEdge
199 && (event.getY() > 0 && event.getY() < screenHeight - 1)) {
200 mCallbacks.onMouseLeaveFromEdge();
201 mMouseHoveringAtEdge = false;
202 }
203 }
204 break;
205 case MotionEvent.ACTION_UP:
206 case MotionEvent.ACTION_CANCEL:
207 mSwipeFireable = false;
208 mDebugFireable = false;
209 mCallbacks.onUpOrCancel();
210 break;
211 default:
212 if (DEBUG) Slog.d(TAG, "Ignoring " + event);
213 }
214 }
215
216 private void captureDown(MotionEvent event, int pointerIndex) {
217 final int pointerId = event.getPointerId(pointerIndex);
218 final int i = findIndex(pointerId);
219 if (DEBUG) Slog.d(TAG, "pointer " + pointerId
220 + " down pointerIndex=" + pointerIndex + " trackingIndex=" + i);
221 if (i != UNTRACKED_POINTER) {
222 mDownX[i] = event.getX(pointerIndex);
223 mDownY[i] = event.getY(pointerIndex);
224 mDownTime[i] = event.getEventTime();
225 if (DEBUG) Slog.d(TAG, "pointer " + pointerId
226 + " down x=" + mDownX[i] + " y=" + mDownY[i]);
227 }
228 }
229
230 protected boolean currentGestureStartedInRegion(Region r) {
231 return r.contains((int) mDownX[0], (int) mDownY[0]);
232 }
233
234 private int findIndex(int pointerId) {
235 for (int i = 0; i < mDownPointers; i++) {
236 if (mDownPointerId[i] == pointerId) {
237 return i;
238 }
239 }
240 if (mDownPointers == MAX_TRACKED_POINTERS || pointerId == MotionEvent.INVALID_POINTER_ID) {
241 return UNTRACKED_POINTER;
242 }
243 mDownPointerId[mDownPointers++] = pointerId;
244 return mDownPointers - 1;
245 }
246
247 private int detectSwipe(MotionEvent move) {
248 final int historySize = move.getHistorySize();
249 final int pointerCount = move.getPointerCount();
250 for (int p = 0; p < pointerCount; p++) {
251 final int pointerId = move.getPointerId(p);
252 final int i = findIndex(pointerId);
253 if (i != UNTRACKED_POINTER) {
254 for (int h = 0; h < historySize; h++) {
255 final long time = move.getHistoricalEventTime(h);
256 final float x = move.getHistoricalX(p, h);
257 final float y = move.getHistoricalY(p, h);
258 final int swipe = detectSwipe(i, time, x, y);
259 if (swipe != SWIPE_NONE) {
260 return swipe;
261 }
262 }
263 final int swipe = detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p));
264 if (swipe != SWIPE_NONE) {
265 return swipe;
266 }
267 }
268 }
269 return SWIPE_NONE;
270 }
271
272 private int detectSwipe(int i, long time, float x, float y) {
273 final float fromX = mDownX[i];
274 final float fromY = mDownY[i];
275 final long elapsed = time - mDownTime[i];
276 if (DEBUG) Slog.d(TAG, "pointer " + mDownPointerId[i]
277 + " moved (" + fromX + "->" + x + "," + fromY + "->" + y + ") in " + elapsed);
278 if (fromY <= mSwipeStartThreshold
279 && y > fromY + mSwipeDistanceThreshold
280 && elapsed < SWIPE_TIMEOUT_MS) {
281 return SWIPE_FROM_TOP;
282 }
283 if (fromY >= screenHeight - mSwipeStartThreshold
284 && y < fromY - mSwipeDistanceThreshold
285 && elapsed < SWIPE_TIMEOUT_MS) {
286 return SWIPE_FROM_BOTTOM;
287 }
288 if (fromX >= screenWidth - mSwipeStartThreshold
289 && x < fromX - mSwipeDistanceThreshold
290 && elapsed < SWIPE_TIMEOUT_MS) {
291 return SWIPE_FROM_RIGHT;
292 }
293 if (fromX <= mSwipeStartThreshold
294 && x > fromX + mSwipeDistanceThreshold
295 && elapsed < SWIPE_TIMEOUT_MS) {
296 return SWIPE_FROM_LEFT;
297 }
298 return SWIPE_NONE;
299 }
300
301 private final class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener {
302
303 private OverScroller mOverscroller;
304
305 FlingGestureDetector() {
306 mOverscroller = new OverScroller(mContext);
307 }
308
309 @Override
310 public boolean onSingleTapUp(MotionEvent e) {
311 if (!mOverscroller.isFinished()) {
312 mOverscroller.forceFinished(true);
313 }
314 return true;
315 }
316 @Override
317 public boolean onFling(MotionEvent down, MotionEvent up,
318 float velocityX, float velocityY) {
319 mOverscroller.computeScrollOffset();
320 long now = SystemClock.uptimeMillis();
321
322 if (mLastFlingTime != 0 && now > mLastFlingTime + MAX_FLING_TIME_MILLIS) {
323 mOverscroller.forceFinished(true);
324 }
325 mOverscroller.fling(0, 0, (int)velocityX, (int)velocityY,
326 Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
327 int duration = mOverscroller.getDuration();
328 if (duration > MAX_FLING_TIME_MILLIS) {
329 duration = MAX_FLING_TIME_MILLIS;
330 }
331 mLastFlingTime = now;
332 mCallbacks.onFling(duration);
333 return true;
334 }
335 }
336
337 interface Callbacks {
338 void onSwipeFromTop();
339 void onSwipeFromBottom();
340 void onSwipeFromRight();
341 void onSwipeFromLeft();
342 void onFling(int durationMs);
343 void onDown();
344 void onUpOrCancel();
345 void onMouseHoverAtTop();
346 void onMouseHoverAtBottom();
347 void onMouseLeaveFromEdge();
348 void onDebug();
349 }
350 }
351
通过代码逻辑可以看到,里面实现了左滑、右滑、上滑、下滑等等全局事件,当检测到对应的事件后,会执行回调方法,具体实现及处理是在 DisplayPolicy.java 里面,之前的版本在 PhoneWindowManager 里面:
DisplayPolicy.java
public class DisplayPolicy {
private final SystemGesturesPointerEventListener mSystemGestures;
......
DisplayPolicy(WindowManagerService service, DisplayContent displayContent) {
mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler,
452 new SystemGesturesPointerEventListener.Callbacks() {
453 @Override
454 public void onSwipeFromTop() {
455 synchronized (mLock) {
456 if (mStatusBar != null) {
457 requestTransientBars(mStatusBar);
458 }
459 checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
460 }
461 }
462
463 @Override
464 public void onSwipeFromBottom() {
465 synchronized (mLock) {
466 if (mNavigationBar != null
467 && mNavigationBarPosition == NAV_BAR_BOTTOM) {
468 requestTransientBars(mNavigationBar);
469 }
470 checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
471 }
472 }
473
474 @Override
475 public void onSwipeFromRight() {
476 ......
489 }
490
491 @Override
492 public void onSwipeFromLeft() {
493 ......
506 }
507
508 @Override
509 public void onFling(int duration) {
510 if (mService.mPowerManagerInternal != null) {
511 mService.mPowerManagerInternal.setPowerBoost(
512 Boost.INTERACTION, duration);
513 }
514 }
534 ......
562 });
// 接口的注册
563 displayContent.registerPointerEventListener(mSystemGestures);
}
}
可以看到,在 DisplayPolicy 的构造方法内部,会创建 SystemGesturesPointerEventListener,并通过 displayContent 的registerPointerEventListener() 进行注册,接下来看一下 DisplayPolicy 构造方法的调用入口在 DisplayContent 的构造函数中实现,:
DisplayContent.java
DisplayContent(Display display, RootWindowContainer root) {
mDisplayPolicy = new DisplayPolicy(mWmService, this);
}
由此可见 DisplayContent 构造的时候创建了对全局手势的监听,然后调用 DisplayContent 的 registerPointerEventListener 注册这个监听,如下:
DisplayContent.java
void registerPointerEventListener(@NonNull PointerEventListener listener) {
4933 mPointerEventDispatcher.registerInputEventListener(listener);
4934 }
至此注册监听的流程完毕。
关于触摸事件从接收、传递、处理在前面的几篇文章里面已经详细分析了,全局手势事件也是大致相同的处理流程,本章仅将涉及全局手势事件处理相关的点来进行分析。
先从注册讲起,我们来看 InputChannel 的生成:
InputManagerService.java
public InputChannel monitorInput(String inputChannelName, int displayId) {
699 if (inputChannelName == null) {
700 throw new IllegalArgumentException("inputChannelName must not be null.");
701 }
702
703 if (displayId < Display.DEFAULT_DISPLAY) {
704 throw new IllegalArgumentException("displayId must >= 0.");
705 }
706
707 return nativeCreateInputMonitor(mPtr, displayId, false /* isGestureMonitor */,
708 inputChannelName, Binder.getCallingPid());
709 }
调用 native 方法 nativeCreateInputMonitor
com_android_server_input_InputManagerService.cpp
static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId,
1604 jboolean isGestureMonitor, jstring nameObj, jint pid) {
1605 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1606
1607 if (displayId == ADISPLAY_ID_NONE) {
1608 std::string message = "InputChannel used as a monitor must be associated with a display";
1609 jniThrowRuntimeException(env, message.c_str());
1610 return nullptr;
1611 }
1612
1613 ......
1615
1616 base::Result<std::unique_ptr<InputChannel>> inputChannel =
1617 im->createInputMonitor(env, displayId, isGestureMonitor, name, pid);
1618
1619 ......
1625
1626 jobject inputChannelObj =
1627 android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
1628 if (!inputChannelObj) {
1629 return nullptr;
1630 }
1631 return inputChannelObj;
1632 }
生成 java 层的 inputChannel 对象并返回。我们接下来看 native 层是怎么构建 inputChannel 的。
com_android_server_input_InputManagerService.cpp
base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor(
518 JNIEnv* /* env */, int32_t displayId, bool isGestureMonitor, const std::string& name,
519 int32_t pid) {
520 ATRACE_CALL();
// 可以知道是通过 InputDispatcher 来生成 InputMonitor
521 return mInputManager->getDispatcher()->createInputMonitor(displayId, isGestureMonitor, name,
522 pid);
523 }
可以知道是通过 InputDispatcher 来生成 InputMonitor
InputDispatcher.cpp
Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5226 bool isGestureMonitor,
5227 const std::string& name,
5228 int32_t pid) {
5229 std::shared_ptr<InputChannel> serverChannel;
5230 std::unique_ptr<InputChannel> clientChannel;
5231 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5232 if (result) {
5233 return base::Error(result) << "Failed to open input channel pair with name " << name;
5234 }
5235
5236 { // acquire lock
5237 ......
5243
5244 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
5245 const sp<IBinder>& token = serverChannel->getConnectionToken();
5246 const int fd = serverChannel->getFd();
5247
5248 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5249 ALOGE("Created a new connection, but the token %p is already known", token.get());
5250 }
5251 mConnectionsByToken.emplace(token, connection);
5252 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5253 this, std::placeholders::_1, token);
5254
5255 auto& monitorsByDisplay =
5256 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
5257 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
5258
5259 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
5260 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5261 displayId, toString(isGestureMonitor), pid);
5262 }
5263
5264 // Wake the looper because some connections have changed.
5265 mLooper->wake();
5266 return clientChannel;
5267 }
主要干了四件事: