【安卓13 源码】Input子系统(2) - input系统与应用进程通信

点击手机屏幕,可以分发input 事件到对应的view,由上一节知道input 是运行在system 进程的,那应用进程与系统进程是如何通讯的呢,相信本文可以给到一点小小的答案。

先给个结论:应用在resume 的时候才去建立与input 服务的联系。其中还创建了Token 对象和WindowState 对象等

/frameworks/base/core/java/android/app/ActivityThread.java

应用执行resume 代码流程

复制代码
4826      @Override
4827      public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
4828              boolean isForward, String reason) {
4829          // If we are getting ready to gc after going to the background, well
4830          // we are back active so skip it.
4831          unscheduleGcIdler();
4832          mSomeActivitiesChanged = true;
4833  
4834          // TODO Push resumeArgs into the activity for consideration
4835          // skip below steps for double-resume and r.mFinish = true case.

// 这里去回调应用的onsesume 方法
4836          if (!performResumeActivity(r, finalStateRequest, reason)) {
4837              return;
4838          }
4839          if (mActivitiesToBeDestroyed.containsKey(r.token)) {
4840              // Although the activity is resumed, it is going to be destroyed. So the following
4841              // UI operations are unnecessary and also prevents exception because its token may
4842              // be gone that window manager cannot recognize it. All necessary cleanup actions
4843              // performed below will be done while handling destruction.
4844              return;
4845          }
4846  
4847          final Activity a = r.activity;
4848  
4849          if (localLOGV) {
4850              Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
4851                      + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
4852          }
4853  
4854          final int forwardBit = isForward
4855                  ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
4856  
4857          // If the window hasn't yet been added to the window manager,
4858          // and this guy didn't finish itself or start another activity,
4859          // then go ahead and add the window.
4860          boolean willBeVisible = !a.mStartedActivity;
4861          if (!willBeVisible) {
4862              willBeVisible = ActivityClient.getInstance().willActivityBeVisible(
4863                      a.getActivityToken());
4864          }
4865          if (r.window == null && !a.mFinished && willBeVisible) {
4866              r.window = r.activity.getWindow();
4867              View decor = r.window.getDecorView();
4868              decor.setVisibility(View.INVISIBLE);
4869              ViewManager wm = a.getWindowManager();
4870              WindowManager.LayoutParams l = r.window.getAttributes();
4871              a.mDecor = decor;
4872              l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
4873              l.softInputMode |= forwardBit;
4874              if (r.mPreserveWindow) {
4875                  a.mWindowAdded = true;
4876                  r.mPreserveWindow = false;
4877                  // Normally the ViewRoot sets up callbacks with the Activity
4878                  // in addView->ViewRootImpl#setView. If we are instead reusing
4879                  // the decor view we have to notify the view root that the
4880                  // callbacks may have changed.
4881                  ViewRootImpl impl = decor.getViewRootImpl();
4882                  if (impl != null) {
4883                      impl.notifyChildRebuilt();
4884                  }
4885              }
4886              if (a.mVisibleFromClient) {
4887                  if (!a.mWindowAdded) {
4888                      a.mWindowAdded = true;

// 这里去增加view,并设置了 mWindowAdded 为true 的。保证只增加一次
4889                      wm.addView(decor, l);

/frameworks/base/core/java/android/view/WindowManagerImpl.java

复制代码
// addview 方法
 145      @Override
146      public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
147          applyTokens(params);
148          mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
149                  mContext.getUserId());
150      }

/frameworks/base/core/java/android/view/WindowManagerGlobal.java

复制代码
// addview 方法
 145      @Override
146      public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
147          applyTokens(params);
148          mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
149                  mContext.getUserId());
150      }

/frameworks/base/core/java/android/view/WindowManagerGlobal.java

复制代码
304      public void addView(View view, ViewGroup.LayoutParams params,
305              Display display, Window parentWindow, int userId) {
306          if (view == null) {
307              throw new IllegalArgumentException("view must not be null");
308          }
。。。。
372              IWindowSession windowlessSession = null;
373              // If there is a parent set, but we can't find it, it may be coming

385              if (windowlessSession == null) {
    // 创建ViewRootImpl 对象,windowlessSession与分屏有关
386                  root = new ViewRootImpl(view.getContext(), display);
387              } else {
388                  root = new ViewRootImpl(view.getContext(), display,
389                          windowlessSession);
390              }
// 给 ViewRootImpl 去设置params 参数
392              view.setLayoutParams(wparams);
393  
394              mViews.add(view);
395              mRoots.add(root);
396              mParams.add(wparams);
397  
398              // do this last because it fires off messages to start doing things
399              try {
    // 去设置view
400                  root.setView(view, wparams, panelParentView, userId);
401              } catch (RuntimeException e) {

/frameworks/base/core/java/android/view/ViewRootImpl.java

复制代码
1099      public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
1100              int userId) {
1101          synchronized (this) {
1102              if (mView == null) {
1103                  mView = view;
。。。。
// 向surfaceflinger 申请vsync ,准备绘制
1195                  requestLayout();
1196                  InputChannel inputChannel = null;
1197                  if ((mWindowAttributes.inputFeatures
1198                          & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
    // 没有该属性,创建 InputChannel对象
1199                      inputChannel = new InputChannel();
1200                  }
。。。。
1212                  try {
1213                      mOrigWindowType = mWindowAttributes.type;
1214                      mAttachInfo.mRecomputeGlobalAttributes = true;
1215                      collectViewAttributes();
1216                      adjustLayoutParamsForCompatibility(mWindowAttributes);
1217                      controlInsetsForCompatibility(mWindowAttributes);
// 一、这里传入了空的 inputChannel,去与input 创建socket 通信。这里还去创建了 windowtoken、windowstate 等对象
1218                      res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
1219                              getHostVisibility(), mDisplay.getDisplayId(), userId,
1220                              mInsetsController.getRequestedVisibilities(), inputChannel, mTempInsets,
1221                              mTempControls);

// 二、创建service 服务端到客户端的回调

1325                  if (inputChannel != null) {
1326                      if (mInputQueueCallback != null) {
1327                          mInputQueue = new InputQueue();
1328                          mInputQueueCallback.onInputQueueCreated(mInputQueue);
1329                      }
// 创建 WindowInputEventReceiver对象,looper 是主线程
1330                      mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
1331                              Looper.myLooper());
1332  
1333                      if (ENABLE_INPUT_LATENCY_TRACKING && mAttachInfo.mThreadedRenderer != null) {
1334                          InputMetricsListener listener = new InputMetricsListener();
1335                          mHardwareRendererObserver = new HardwareRendererObserver(
1336                                  listener, listener.data, mHandler, true /*waitForPresentTime*/);
1337                          mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
1338                      }
1339                  }
1340  
1341                  view.assignParent(this);
1342                  mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
1343                  mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
1344  
1345                  if (mAccessibilityManager.isEnabled()) {
1346                      mAccessibilityInteractionConnectionManager.ensureConnection();
1347                  }
1348  
1349                  if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
1350                      view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
1351                  }
1352  

// 设置input 事件接收后的回调链
1353                  // Set up the input pipeline.
1354                  CharSequence counterSuffix = attrs.getTitle();
1355                  mSyntheticInputStage = new SyntheticInputStage();
1356                  InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);
1357                  InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,
1358                          "aq:native-post-ime:" + counterSuffix);
1359                  InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);
1360                  InputStage imeStage = new ImeInputStage(earlyPostImeStage,
1361                          "aq:ime:" + counterSuffix);
1362                  InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);
1363                  InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,
1364                          "aq:native-pre-ime:" + counterSuffix);
1365  
1366                  mFirstInputStage = nativePreImeStage;
1367                  mFirstPostImeInputStage = earlyPostImeStage;
1368                  mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
1369  
1370                  AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
1371              }
1372          }

一、传入空的 inputChannel,去与input 创建socket 通信。

调用mWindowSession.addToDisplay携带着InputChannel,addToDisplay最终调用到WMS的addwindow。

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

复制代码
205      public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
206              int viewVisibility, int displayId, int userId, InsetsVisibilities requestedVisibilities,
207              InputChannel outInputChannel, InsetsState outInsetsState,
208              InsetsSourceControl[] outActiveControls) {
209          return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
210                  requestedVisibilities, outInputChannel, outInsetsState, outActiveControls);
211      }

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

复制代码
449      public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
1450              int displayId, int requestUserId, InsetsVisibilities requestedVisibilities,
1451              InputChannel outInputChannel, InsetsState outInsetsState,
1452              InsetsSourceControl[] outActiveControls) {
1453          Arrays.fill(outActiveControls, null);
1454          int[] appOp = new int[1];
1455          final boolean isRoundedCornerOverlay = (attrs.privateFlags
1456                  & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
1457          int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
1458                  appOp);
1459          if (res != ADD_OKAY) {
1460              return res;
1461          }
。。。。。。。。
1682              final boolean openInputChannels = (outInputChannel != null
1683                      && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
1684              if  (openInputChannels) {
    // 通过windowstate 去打开channel,给outInputChannel 赋值
1685                  win.openInputChannel(outInputChannel);
1686              }
1687  

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

复制代码
2766      void openInputChannel(InputChannel outInputChannel) {
2767          if (mInputChannel != null) {
2768              throw new IllegalStateException("Window already has an input channel.");
2769          }
2770          String name = getName();

// 通过wms 的ims 去创建inputchannel
2771          mInputChannel = mWmService.mInputManager.createInputChannel(name);
2772          mInputChannelToken = mInputChannel.getToken();
2773          mInputWindowHandle.setToken(mInputChannelToken);
2774          mWmService.mInputToWindowMap.put(mInputChannelToken, this);
2775          if (outInputChannel != null) {
2776              mInputChannel.copyTo(outInputChannel);
2777          } else {
2778              // If the window died visible, we setup a fake input channel, so that taps
2779              // can still detected by input monitor channel, and we can relaunch the app.
2780              // Create fake event receiver that simply reports all events as handled.
2781              mDeadWindowEventReceiver = new DeadWindowEventReceiver(mInputChannel);
2782          }
2783      }

/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

复制代码
784      public InputChannel createInputChannel(String name) {
785          return mNative.createInputChannel(name);
786      }

// mNative 对象是 NativeImpl
406          NativeInputManagerService getNativeService(InputManagerService service) {
407              return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
408          }

/frameworks/base/services/core/java/com/android/server/input/NativeInputManagerService.java

复制代码
194      class NativeImpl implements NativeInputManagerService {
195          /** Pointer to native input manager service object, used by native code. */
196          @SuppressWarnings({"unused", "FieldCanBeLocal"})
197          private final long mPtr;
198  
199          NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
    // 调用native 层初始化方法
200              mPtr = init(service, context, messageQueue);
201          }

// 调用native 层createInputChannel 方法
229          public native InputChannel createInputChannel(String name);

/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

复制代码
2322          {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;",
2323           (void*)nativeCreateInputChannel},

1592  
1593  static jobject nativeCreateInputChannel(JNIEnv* env, jobject nativeImplObj, jstring nameObj) {
1594      NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
1595  
1596      ScopedUtfChars nameChars(env, nameObj);
1597      std::string name = nameChars.c_str();
1598  

// NativeInputManager 的 createInputChannel 方法
1599      base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(name);
1600  
1601      if (!inputChannel.ok()) {
1602          std::string message = inputChannel.error().message();
1603          message += StringPrintf(" Status=%d", static_cast<int>(inputChannel.error().code()));
1604          jniThrowRuntimeException(env, message.c_str());
1605          return nullptr;
1606      }
1607  

// 回调java 层的方法
1608      jobject inputChannelObj =
1609              android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
1610      if (!inputChannelObj) {
1611          return nullptr;
1612      }
1613  
1614      android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1615              handleInputChannelDisposed, im);
1616      return inputChannelObj;
1617  }

512  base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel(
513          const std::string& name) {
514      ATRACE_CALL();
// 调用InputDispatcher 的方法 createInputChannel
515      return mInputManager->getDispatcher().createInputChannel(name);
516  }

/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

复制代码
5450  Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
5451      if (DEBUG_CHANNEL_CREATION) {
5452          ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5453      }
5454  
5455      std::unique_ptr<InputChannel> serverChannel;
5456      std::unique_ptr<InputChannel> clientChannel;

// InputChannel 去创建socket 通信
5457      status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
5458  
5459      if (result) {
5460          return base::Error(result) << "Failed to open input channel pair with name " << name;
5461      }
5462  
5463      { // acquire lock
5464          std::scoped_lock _l(mLock);
5465          const sp<IBinder>& token = serverChannel->getConnectionToken();
5466          int fd = serverChannel->getFd();
// 创建服务器端的 Connection,serverChannel作为参数
5467          sp<Connection> connection =
5468                  new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
5469  
5470          if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5471              ALOGE("Created a new connection, but the token %p is already known", token.get());
5472          }

// 将token作为客户端的标志值保存到 mConnectionsByToken,在事件分发的时候可以使用
5473          mConnectionsByToken.emplace(token, connection);
5474  
5475          std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5476                                                              this, std::placeholders::_1, token);
5477  

// 将 handleReceiveCallback 函数增加到fd 的监听中,应用客户端与input 服务端通信的时候,会回调 handleReceiveCallback
5478          mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
5479      } // release lock
5480  
5481      // Wake the looper because some connections have changed.
5482      mLooper->wake();
// 这里返回客户端inputchannel 给应用
5483      return clientChannel;
5484  }

调用socketpair函数创建一对相互连接的socket,然后创建了一对InputChannel,分别持有一个socket,一个作为客户端一个作为服务端,这样分别持有这两个InputChannel的两端就可以通过socket通信了。

// =========InputChannel 去创建socket 通信========

复制代码
334  status_t InputChannel::openInputChannelPair(const std::string& name,
335                                              std::unique_ptr<InputChannel>& outServerChannel,
336                                              std::unique_ptr<InputChannel>& outClientChannel) {
337      int sockets[2];
// 创建socket
338      if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
339          status_t result = -errno;
340          ALOGE("channel '%s' ~ Could not create socket pair.  errno=%s(%d)", name.c_str(),
341                strerror(errno), errno);
342          outServerChannel.reset();
343          outClientChannel.reset();
344          return result;
345      }
346  
347      int bufferSize = SOCKET_BUFFER_SIZE;
// 设置双向通信
348      setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
349      setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
350      setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
351      setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
352  
// 服务器端和客户端都是使用相同的token
353      sp<IBinder> token = new BBinder();
354  
355      std::string serverChannelName = name + " (server)";
356      android::base::unique_fd serverFd(sockets[0]);
// 创建服务器端的 InputChannel 对象
357      outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token);
358  
359      std::string clientChannelName = name + " (client)";
360      android::base::unique_fd clientFd(sockets[1]);
// 创建客户器端的 InputChannel 对象
361      outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token);
362      return OK;
363  }

309  std::unique_ptr<InputChannel> InputChannel::create(const std::string& name,
310                                                     android::base::unique_fd fd, sp<IBinder> token) {
311      const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
312      if (result != 0) {
313          LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
314                           strerror(errno));
315          return nullptr;
316      }
317      // using 'new' to access a non-public constructor
318      return std::unique_ptr<InputChannel>(new InputChannel(name, std::move(fd), token));
319  }

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

复制代码
2766      void openInputChannel(InputChannel outInputChannel) {
2767          if (mInputChannel != null) {
2768              throw new IllegalStateException("Window already has an input channel.");
2769          }
2770          String name = getName();

// 最终获取到创建的 nputchannel
2771          mInputChannel = mWmService.mInputManager.createInputChannel(name);
// 获取到token,该token 的值与 服务器端ims 的值是一致的。可以一一对应socket 通信
2772          mInputChannelToken = mInputChannel.getToken();
// 将其设置给 InputWindowHandle
2773          mInputWindowHandle.setToken(mInputChannelToken);
2774          mWmService.mInputToWindowMap.put(mInputChannelToken, this);
2775          if (outInputChannel != null) {
    // 最后将其拷贝给 mInputChannel
2776              mInputChannel.copyTo(outInputChannel);
2777          } else {
2778              // If the window died visible, we setup a fake input channel, so that taps
2779              // can still detected by input monitor channel, and we can relaunch the app.
2780              // Create fake event receiver that simply reports all events as handled.
2781              mDeadWindowEventReceiver = new DeadWindowEventReceiver(mInputChannel);
2782          }
2783      }

二、创建service 服务端到客户端的回调

/frameworks/base/core/java/android/view/ViewRootImpl.java

复制代码
// 创建 WindowInputEventReceiver对象,looper 是主线程
1330                      mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
1331                              Looper.myLooper());

// 创建 WindowInputEventReceiver对象,继承了 InputEventReceiver对象
8953      final class WindowInputEventReceiver extends InputEventReceiver {
8954          public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
8955              super(inputChannel, looper);
8956          }
8957  

// 会回调下列的方法,然后走调用链 enqueueInputEvent
8958          @Override
8959          public void onInputEvent(InputEvent event) {
8960              Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");
8961              List<InputEvent> processedEvents;
8962              try {
8963                  processedEvents =
8964                      mInputCompatProcessor.processInputEventForCompatibility(event);
8965              } finally {
8966                  Trace.traceEnd(Trace.TRACE_TAG_VIEW);
8967              }
8968              if (processedEvents != null) {
8969                  if (processedEvents.isEmpty()) {
8970                      // InputEvent consumed by mInputCompatProcessor
8971                      finishInputEvent(event, true);
8972                  } else {
8973                      for (int i = 0; i < processedEvents.size(); i++) {
8974                          enqueueInputEvent(
8975                                  processedEvents.get(i), this,
8976                                  QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
8977                      }
8978                  }
8979              } else {
8980                  enqueueInputEvent(event, this, 0, true);
8981              }
8982          }

// InputEventReceiver对象的构造方法

/frameworks/base/core/java/android/view/InputEventReceiver.java

复制代码
69      public InputEventReceiver(InputChannel inputChannel, Looper looper) {
70          if (inputChannel == null) {
71              throw new IllegalArgumentException("inputChannel must not be null");
72          }
73          if (looper == null) {
74              throw new IllegalArgumentException("looper must not be null");
75          }
76  
77          mInputChannel = inputChannel;
78          mMessageQueue = looper.getQueue();

// 调用native 层的初始化方法
79          mReceiverPtr = nativeInit(new WeakReference<InputEventReceiver>(this),
80                  inputChannel, mMessageQueue);
81  
82          mCloseGuard.open("InputEventReceiver.dispose");
83      }

/frameworks/base/core/jni/android_view_InputEventReceiver.cpp

复制代码
493  static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
494          jobject inputChannelObj, jobject messageQueueObj) {
495      std::shared_ptr<InputChannel> inputChannel =
496              android_view_InputChannel_getInputChannel(env, inputChannelObj);
497      if (inputChannel == nullptr) {
498          jniThrowRuntimeException(env, "InputChannel is not initialized.");
499          return 0;
500      }
501  
502      sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
503      if (messageQueue == nullptr) {
504          jniThrowRuntimeException(env, "MessageQueue is not initialized.");
505          return 0;
506      }
507  

// 创建 NativeInputEventReceiver 对象
508      sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
509              receiverWeak, inputChannel, messageQueue);
// 初始化
510      status_t status = receiver->initialize();
511      if (status) {
512          std::string message = android::base::
513                  StringPrintf("Failed to initialize input event receiver.  status=%s(%d)",
514                               statusToString(status).c_str(), status);
515          jniThrowRuntimeException(env, message.c_str());
516          return 0;
517      }
518  
519      receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
520      return reinterpret_cast<jlong>(receiver.get());
521  }


124  NativeInputEventReceiver::NativeInputEventReceiver(
125          JNIEnv* env, jobject receiverWeak, const std::shared_ptr<InputChannel>& inputChannel,
126          const sp<MessageQueue>& messageQueue)
127        : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
128          mInputConsumer(inputChannel),
129          mMessageQueue(messageQueue),
130          mBatchedInputEventPending(false),
131          mFdEvents(0) {
132      if (kDebugDispatchCycle) {
133          ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName().c_str());
134      }
135  }

// 初始化的方法
142  status_t NativeInputEventReceiver::initialize() {
143      setFdEvents(ALOOPER_EVENT_INPUT);
144      return OK;
145  }

184  void NativeInputEventReceiver::setFdEvents(int events) {
185      if (mFdEvents != events) {
186          mFdEvents = events;
// events 是 ALOOPER_EVENT_INPUT
187          int fd = mInputConsumer.getChannel()->getFd();
188          if (events) {
    // 在Looper 代码中,如果有socket 通信,会回调 handleEvent
189              mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr);
190          } else {
191              mMessageQueue->getLooper()->removeFd(fd);
192          }
193      }
194  }

263  int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
264      // Allowed return values of this function as documented in LooperCallback::handleEvent
265      constexpr int REMOVE_CALLBACK = 0;
266      constexpr int KEEP_CALLBACK = 1;
267  
268      if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
269          // This error typically occurs when the publisher has closed the input channel
270          // as part of removing a window or finishing an IME session, in which case
271          // the consumer will soon be disposed as well.
272          if (kDebugDispatchCycle) {
273              ALOGD("channel '%s' ~ Publisher closed input channel or an error occurred. events=0x%x",
274                    getInputChannelName().c_str(), events);
275          }
276          return REMOVE_CALLBACK;
277      }
278  

// 是下列的event,去消费input事件
279      if (events & ALOOPER_EVENT_INPUT) {
280          JNIEnv* env = AndroidRuntime::getJNIEnv();
281          status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
282          mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
283          return status == OK || status == NO_MEMORY ? KEEP_CALLBACK : REMOVE_CALLBACK;
284      }

总结:

  • 创建了一对相互连接的Socket,用来通信
  • 创建了一对InputChannel,分别持有一个socket,使InputChannel成为实现两端通信的信使。
  • 两个InputChannel分别作为客户端channel和服务端channel,服务端channel给InputDispatcher持有,客户端channel给InputEventReceiver持有。
  • 两个socket的fd分别注册到对应端的Looper,有数据传输会唤醒对端处理。
相关推荐
API小爬虫11 分钟前
使用PHP爬虫获取淘宝App商品详情?
android·爬虫·php
一笑的小酒馆9 小时前
Android在ksp中简单使用Room
android
meimeiqian11 小时前
flutter android端抓包工具
android·flutter
Android技术之家11 小时前
谷歌决定终止开源Android以及对开发者的影响
android·开源
每次的天空12 小时前
Android Jetpack学习总结(源码级理解)
android·学习·android jetpack
木子庆五12 小时前
Android设计模式之代理模式
android·设计模式·代理模式
在雨季等你13 小时前
创业之旅 - 反思 - 整改 - 新的方向 - 诚邀
android
Long_poem13 小时前
【自学笔记】PHP语言基础知识点总览-持续更新
android·笔记·php
fatiaozhang952714 小时前
晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包
android·游戏·adb·华为·电视盒子·机顶盒rom·魔百盒固件
行墨15 小时前
Kotlin语言的==与===比较操作
android