Android Input 流程分析

1. addView 流程

addView()一般用来动态添加View,LinearLayout、RelativeLayout 添加子控件都可以用addView()

addView 最终在WindowManager ->  WindowManagerImpl ->WindowManagerGlobal -> ViewRootImpl.setView()

OnCreated阶段:

frameworks/base/core/java/android/app/Activity.java
  final void attach(Context context, ActivityThread aThread,){
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
  }
  public Window getWindow() {
    return mWindow;
  }

  public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
  }

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
  private LayoutInflater mLayoutInflater;
  public void setContentView(int layoutResID) {
    if (mContentParent == null) {
      installDecor();
    }
    mLayoutInflater.inflate(layoutResID, mContentParent);
    mContentParent.requestApplyInsets();
    final Callback cb = getCallback();
  }

// 首次setContentView会创建DecorView,调用mLayoutInflater.inflate,把resId文件映射成各种view
frameworks/base/core/java/android/view/LayoutInflater.java
  public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
    return inflate(resource, root, root != null);
  }
  public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot){
    View result = root;
    root.addView(temp, params);
  }

frameworks/base/core/java/com/android/internal/policy/DecorView.java
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {}
//public class FrameLayout extends ViewGroup {}

frameworks/base/core/java/android/view/ViewGroup.java
public void addView(View child, LayoutParams params) {
  addView(child, -1, params);
}
public void addView(View child, int index, LayoutParams params) {
  requestLayout();
  invalidate(true);
  // addViewInner  主要是把子view添加到childViews数组中
  addViewInner(child, index, params, false);
}

 OnResume阶段:

frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleResumeActivity(){
  final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
  r.activity.makeVisible();
}
void makeVisible() {
  if (!mWindowAdded) {
    ViewManager wm = getWindowManager();
    // WindowManager.addView()
    wm.addView(mDecor, getWindow().getAttributes());
    mWindowAdded = true;
  }
  mDecor.setVisibility(View.VISIBLE);
}

frameworks/base/core/java/android/view/ViewManager.java
public interface ViewManager{
  public void addView(View view, ViewGroup.LayoutParams params);
  public void updateViewLayout(View view, ViewGroup.LayoutParams params);
  public void removeView(View view);
}
frameworks/base/core/java/android/view/WindowManager.java
public interface WindowManager extends ViewManager {
}

frameworks/base/core/java/android/view/WindowManagerImpl.java
public final class WindowManagerImpl implements WindowManager {
  private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
  
  @Override
  public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
  }
}

frameworks/base/core/java/android/view/WindowManagerGlobal.java
public final class WindowManagerGlobal {
  private static WindowManagerGlobal sDefaultWindowManager;
  public static WindowManagerGlobal getInstance() {
    if (sDefaultWindowManager == null) {
      sDefaultWindowManager = new WindowManagerGlobal();
    }
    return sDefaultWindowManager;
  }
  public void addView(View view, ViewGroup.LayoutParams params,
    Display display, Window parentWindow) {
    ViewRootImpl root;
    root = new ViewRootImpl(view.getContext(), display);
    root.setView(view, wparams, panelParentView);
  }
}

setView 时 new InputChannel(),作为参数传入到 Session中。ViewRootImpl.setView() -> Session.addToDisplay() -> WindowManagerService.addWindow() -> WinState.openInputChannel(outInputChannel)

frameworks/base/core/java/android/view/ViewRootImpl.java
final IWindowSession mWindowSession;
InputChannel mInputChannel;
WindowInputEventReceiver mInputEventReceiver;
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
  requestLayout();
  if ((mWindowAttributes.inputFeatures
      & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
    mInputChannel = new InputChannel();
  }
  //通过Binder调用,进入system进程的Session,这里将客户端的InputChannel对象作为参数传入
  res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
             getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
             mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
             mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);

  if (mInputChannel != null) {
    mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                            Looper.myLooper());
  }
}

frameworks/base/services/core/java/com/android/server/wm/Session.java
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
  final WindowManagerService mService;
  public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
    DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
           outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
  }
}

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
  DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
  final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);

  final boolean openInputChannels = (outInputChannel != null
                    && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
  if  (openInputChannels) {
    win.openInputChannel(outInputChannel);
  }
}

frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void openInputChannel(InputChannel outInputChannel) {
  String name = getName();
  // 返回两个 InputChannel, 0 通过 mService.mInputManager.registerInputChannel 注册
  // 1 通过 transferTo 给 outInputChannel
  InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
  mInputChannel = inputChannels[0];
  mClientChannel = inputChannels[1];
  mInputWindowHandle.inputChannel = inputChannels[0];
  if (outInputChannel != null) {
    mClientChannel.transferTo(outInputChannel);
    mClientChannel.dispose();
  }

  mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);
}
frameworks/base/core/java/android/view/InputChannel.java
public void transferTo(InputChannel outParameter) {
  nativeTransferTo(outParameter);
}
frameworks/base/core/jni/android_view_InputChannel.cpp
static const JNINativeMethod gInputChannelMethods[] = {
  { "nativeTransferTo", "(Landroid/view/InputChannel;)V",
  (void*)android_view_InputChannel_nativeTransferTo },
}
static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,
    jobject otherObj) {
  NativeInputChannel* nativeInputChannel =
        android_view_InputChannel_getNativeInputChannel(env, obj);
    android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel);
    android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
}

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
  public InputChannel monitorInput(String inputChannelName) {
    // channelPair[0] ->  serverChannel, channelPair[1] ->  clientChannel,实际  native 返回
    InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
    
    //重要!!! 传入inputChannels[0] 即 serverChannel
    nativeRegisterInputChannel(mPtr, inputChannels[0], null, true);
    return inputChannels[1];
  }
  public void registerInputChannel(InputChannel inputChannel,
            InputWindowHandle inputWindowHandle) {
    nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);
  }

  public InputManagerService(Context context) {
    mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
  }
  public void start() {
    nativeStart(mPtr);
  }

frameworks/base/core/java/android/view/InputChannel.java
  public static InputChannel[] openInputChannelPair(String name) {
    return nativeOpenInputChannelPair(name);
  }

2. OpenInputChannelPair&nativeRegisterInputChannel

图片从 Android输入系统之InputChannel(上)_区块链斜杠青年(爱踢门)-CSDN博客 拷贝过来

frameworks/base/core/jni/android_view_InputChannel.cpp
OpenInputChannelPair:
static const JNINativeMethod gInputChannelMethods[] = {
  { "nativeOpenInputChannelPair", "(Ljava/lang/String;)[Landroid/view/InputChannel;",
          (void*)android_view_InputChannel_nativeOpenInputChannelPair },
}
// channelPair[0] ->  serverChannel, channelPair[1] ->  clientChannel 
static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(){
  sp<InputChannel> serverChannel;
  sp<InputChannel> clientChannel;

  // frameworks/native/libs/input/InputTransport.cpp 中创建sockets
  // serverChannel -> name + " (server)", clientChannel -> name + " (client)";
  status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
  jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);
  
  jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
            std::make_unique<NativeInputChannel>(serverChannel));
  jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
            std::make_unique<NativeInputChannel>(clientChannel));

  env->SetObjectArrayElement(channelPair, 0, serverChannelObj);
  env->SetObjectArrayElement(channelPair, 1, clientChannelObj);
  return channelPair;
}
static jobject android_view_InputChannel_createInputChannel(){
  android_view_InputChannel_setNativeInputChannel(env, inputChannelObj,
                 nativeInputChannel.release());
  return inputChannelObj;
}
static void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj,
        NativeInputChannel* nativeInputChannel) {
    env->SetLongField(inputChannelObj, gInputChannelClassInfo.mPtr,
             reinterpret_cast<jlong>(nativeInputChannel));
}

nativeInit/nativeStart/nativeRegisterInputChannel:
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static const JNINativeMethod gInputManagerMethods[] = {
  { "nativeInit",
            "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)J",
            (void*) nativeInit },
  { "nativeStart", "(J)V",
            (void*) nativeStart },
  { "nativeRegisterInputChannel",
            "(JLandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;Z)V",
            (void*) nativeRegisterInputChannel },
}
static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,jlong ptr,
  jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor){
  NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
  sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
  sp<InputWindowHandle> inputWindowHandle =
            android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
  status_t status = im->registerInputChannel(
            env, inputChannel, inputWindowHandle, monitor);
}
status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */,
        const sp<InputChannel>& inputChannel,
        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
    ATRACE_CALL();
  return mInputManager->getDispatcher()->registerInputChannel(
          inputChannel, inputWindowHandle, monitor);
}

  static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
      messageQueue->getLooper());
  }
  static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
    
    status_t result = im->getInputManager()->start();
  }

  NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();
    sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
  }
  
frameworks/native/services/inputflinger/InputManager.cpp
  InputManager::InputManager(
      const sp<EventHubInterface>& eventHub,
      const sp<InputReaderPolicyInterface>& readerPolicy,
      const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
    initialize();
  }
  void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
  }
 
  status_t InputManager::start() {
    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
  }

system/core/libutils/include/utils/Thread.h
  class Thread : virtual public RefBase {
    // Start the thread in threadLoop() which needs to be implemented.
    virtual status_t    run(    const char* name,
                                int32_t priority = PRIORITY_DEFAULT,
                                size_t stack = 0);
    virtual bool        threadLoop() = 0;
  }
system/core/libutils/Threads.cpp
  //所以 xxxThread->run() 会调到其对应的 threadLoop()方法中
  status_t Thread::run(const char* name, int32_t priority, size_t stack) {
    if (mCanCallJava) {
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
  }
  int Thread::_threadLoop(void* user) {
    Thread* const self = static_cast<Thread*>(user);
    do {
      result = self->threadLoop();
    }
  }

3. InputDispatcher

InputDispatcher:
frameworks/native/services/inputflinger/InputDispatcher.h
  class InputDispatcherThread : public Thread {
    private:
    virtual bool threadLoop();
    sp<InputDispatcherInterface> mDispatcher;
  }
  class InputDispatcher : public InputDispatcherInterface {
    
    class Connection : public RefBase {
      // Queue of events that need to be published to the connection.
      Queue<DispatchEntry> outboundQueue;
    }
    
    EventEntry* mPendingEvent;
    Queue<EventEntry> mInboundQueue;
    Queue<EventEntry> mRecentQueue;
    Queue<CommandEntry> mCommandQueue;
  }
 
frameworks/native/services/inputflinger/InputDispatcher.cpp
status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
  sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
  int fd = inputChannel->getFd();
  mConnectionsByFd.add(fd, connection);
  if (monitor) {
	mMonitoringChannels.push(inputChannel);
  }
  mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
}
class Connection : public RefBase {
public:
  sp<InputChannel> inputChannel;
  sp<InputWindowHandle> inputWindowHandle;
  InputPublisher inputPublisher;
}
InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
        monitor(monitor),
        inputPublisher(inputChannel), inputPublisherBlocked(false) {
}

  InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
  : mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false){
    mLooper = new Looper(false);
  }
  
  bool InputDispatcherThread::threadLoop() {
    mDispatcher->dispatchOnce();
    return true;
  }
  void InputDispatcher::dispatchOnce() {
    if (!haveCommandsLocked()) {
        dispatchOnceInnerLocked(&nextWakeupTime);
    }
    if (runCommandsLockedInterruptible()) {
        nextWakeupTime = LONG_LONG_MIN;
    }
    mLooper->pollOnce(timeoutMillis);
  }
  void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    mPendingEvent = mInboundQueue.dequeueAtHead();
    switch (mPendingEvent->type) {
      case EventEntry::TYPE_KEY: {
        done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
        break;
      }
      case EventEntry::TYPE_MOTION: {
        done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
        break;
      }
    }
    if (done) {
      releasePendingEventLocked();
    }
  }
  
  bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
        DropReason* dropReason, nsecs_t* nextWakeupTime) {
    Vector<InputTarget> inputTargets;
    int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
            entry, inputTargets, nextWakeupTime);
    setInjectionResultLocked(entry, injectionResult);
    addMonitoringTargetsLocked(inputTargets);
    
    dispatchEventLocked(currentTime, entry, inputTargets);
  }
  void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
    pokeUserActivityLocked(eventEntry);
    for (size_t i = 0; i < inputTargets.size(); i++) {
      const InputTarget& inputTarget = inputTargets.itemAt(i);
      ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
      if (connectionIndex >= 0) {
        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
        prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
      }
    }
  }
  void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,xxx){
    if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
      enqueueDispatchEntriesLocked(currentTime, connection,
                    splitMotionEntry, inputTarget);
    }
    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
  }
  void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,xxx){
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_IS);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
    
    if (wasEmpty && !connection->outboundQueue.isEmpty()) {
        startDispatchCycleLocked(currentTime, connection);
    }
  }
  void InputDispatcher::enqueueDispatchEntryLocked(){
    DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
            inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
            inputTarget->scaleFactor);
    switch (eventEntry->type) {
    case EventEntry::TYPE_KEY: {
      KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
      dispatchEntry->resolvedAction = keyEntry->action;
      dispatchEntry->resolvedFlags = keyEntry->flags;
      break;
    }

    // Enqueue the dispatch entry.
    connection->outboundQueue.enqueueAtTail(dispatchEntry);
    traceOutboundQueueLengthLocked(connection);
  }
  
  void InputDispatcher::startDispatchCycleLocked(){
    while (connection->status == Connection::STATUS_NORMAL
      && !connection->outboundQueue.isEmpty()) {
      DispatchEntry* dispatchEntry = connection->outboundQueue.head;
      dispatchEntry->deliveryTime = currentTime;
      
      EventEntry* eventEntry = dispatchEntry->eventEntry;
      switch (eventEntry->type) {
        case EventEntry::TYPE_KEY: {
          KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
          status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
            keyEntry->deviceId, keyEntry->source,
            dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
            keyEntry->keyCode, keyEntry->scanCode,
            keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
            keyEntry->eventTime);
        }
      }
    }
  }
  
  
  void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
    KeyEvent event;
    event.initialize(args->deviceId, args->source, args->action,
            flags, keyCode, args->scanCode, metaState, 0,
            args->downTime, args->eventTime);
    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
    
    KeyEntry* newEntry = new KeyEntry(args->eventTime,
                args->deviceId, args->source, policyFlags,
                args->action, flags, keyCode, args->scanCode,
                metaState, repeatCount, args->downTime);
    needWake = enqueueInboundEventLocked(newEntry);
    if (needWake) {
        mLooper->wake();// 唤醒 InputReader
    }
  }
  // 通过 jni 调到 java 层,其实就是PhoneWindowManager先做一次事件拦截处理操作
  void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
        uint32_t& policyFlags) {
    JNIEnv* env = jniEnv();
    jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
    env->CallIntMethod(mServiceObj,
                    gServiceClassInfo.interceptKeyBeforeQueueing,
                    keyEventObj, policyFlags);
    handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
  }
  
  //这里将keyArgs转换成KeyEntery这种数据封装,并添加到InputDispatcher的mInboundQueue里,最后唤醒InputDispacher线程
  bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
    mInboundQueue.enqueueAtTail(entry);
    switch (entry->type) {
    case EventEntry::TYPE_KEY: {
      KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
      break;
    }
    case EventEntry::TYPE_MOTION: {
      MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
    }
    return needWake;
  }
  

frameworks/native/libs/input/InputTransport.cpp
status_t InputChannel::openInputChannelPair(const std::string& name,
        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
  int sockets[2];
  socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
  
  std::string serverChannelName = name;
  serverChannelName += " (server)";
  outServerChannel = new InputChannel(serverChannelName, sockets[0]);
  
  std::string clientChannelName = name;
  clientChannelName += " (client)";
  outClientChannel = new InputChannel(clientChannelName, sockets[1]);
}

// 在 InputDispatcher 中 new Connection() 构造 InputPublisher 对象
InputPublisher::InputPublisher(const sp<InputChannel>& channel) : mChannel(channel) {}
status_t InputPublisher::publishKeyEvent(){
  InputMessage msg;
  msg.header.type = InputMessage::TYPE_KEY;
  msg.body.key.seq = seq;
  msg.body.key.deviceId = deviceId;
  msg.body.key.keyCode = keyCode;
  msg.body.key.scanCode = scanCode;
  
  return mChannel->sendMessage(&msg);
}
status_t InputPublisher::publishMotionEvent(){
  InputMessage msg;
  msg.header.type = InputMessage::TYPE_MOTION;
  return mChannel->sendMessage(&msg);
}

// 建立两个channel, 用来通信,我们这里的inputdispatch相当于一个channel用来分发事件,
// 还有一个通来接收,在android_view_InputEventReceiver.cpp中
status_t InputChannel::sendMessage(const InputMessage* msg) {
  const size_t msgLength = msg->size();
  InputMessage cleanMsg;
  msg->getSanitizedCopy(&cleanMsg);
  do {
    nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
  } while (nWrite == -1 && errno == EINTR); 
}


status_t InputConsumer::consume(InputEventFactoryInterface* factory,
        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent,
        int32_t* displayId) {
  while (!*outEvent) {
    status_t result = mChannel->receiveMessage(&mMsg);
    switch (mMsg.header.type) {
      case InputMessage::TYPE_KEY: {
        KeyEvent* keyEvent = factory->createKeyEvent();
        initializeKeyEvent(keyEvent, &mMsg);
        *outSeq = mMsg.body.key.seq;
        *outEvent = keyEvent;
        break;     
      }
    }
  }
}
status_t InputChannel::receiveMessage(InputMessage* msg) {
  do {
        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
  } while (nRead == -1 && errno == EINTR);
  
}

4.InputReader

frameworks/native/services/inputflinger/InputReader.h
  class InputReaderThread : public Thread {
    sp<InputReaderInterface> mReader;
    virtual bool threadLoop();
  }
frameworks/native/services/inputflinger/InputReader.cpp
  InputReader::InputReader(const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& policy,
        const sp<InputListenerInterface>& listener) :
        mContext(this), mEventHub(eventHub), mPolicy(policy),
        mGlobalMetaState(0), mGeneration(1),
        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    mQueuedListener = new QueuedInputListener(listener);
  }
  void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
    if (when < mNextTimeout) {
        mNextTimeout = when;
        mEventHub->wake();// 调用到EventHub的 wake()方法
    }
  }
  
  bool InputReaderThread::threadLoop() {
    mReader->loopOnce();
  }
  void InputReader::loopOnce() {
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
    if (count) {
        processEventsLocked(mEventBuffer, count);
    }

	if (inputDevicesChanged) {
   	  mPolicy->notifyInputDevicesChanged(inputDevices);
    }
   
    mQueuedListener->flush(); // QueuedInputListener::flush() -> args->notify()
  }
  void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {
      int32_t type = rawEvent->type;
      if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
        processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
      }else {
		switch (rawEvent->type) {
		  case EventHubInterface::DEVICE_ADDED:
		    addDeviceLocked(rawEvent->when, rawEvent->deviceId);
     	    break;
		  case EventHubInterface::DEVICE_REMOVED:
			removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
			break;
		  case EventHubInterface::FINISHED_DEVICE_SCAN:
			handleConfigurationChangedLocked(rawEvent->when);
			break;
		  }
      }
    }
  }
  
  //DEVICE_ADDED
  void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
    device->configure(when, &mConfig, 0);
    device->reset(when);
    mDevices.add(deviceId, device);
  }
  InputDevice* InputReader::createDeviceLocked() {
    device->addMapper(new SwitchInputMapper(device));
    device->addMapper(new RotaryEncoderInputMapper(device));
    device->addMapper(new VibratorInputMapper(device));
    device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
    device->addMapper(new CursorInputMapper(device));
    device->addMapper(new MultiTouchInputMapper(device));
  }
  void InputDevice::addMapper(InputMapper* mapper) {
    mMappers.add(mapper);
  }
  
  // processEventsForDeviceLocked()
  void InputReader::processEventsForDeviceLocked(int32_t deviceId,
        const RawEvent* rawEvents, size_t count) {
    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    InputDevice* device = mDevices.valueAt(deviceIndex);
    device->process(rawEvents, count);
  }
  void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    size_t numMappers = mMappers.size();
    for (size_t i = 0; i < numMappers; i++) {
      InputMapper* mapper = mMappers[i];
      mapper->process(rawEvent);
    }
  }
  // 以KeyboardInputMapper 为例
  class KeyboardInputMapper : public InputMapper {}
  void KeyboardInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
      case EV_KEY: {
        int32_t scanCode = rawEvent->code;
        if (isKeyboardOrGamepadKey(scanCode)) {
          processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
        }
        break;
      }
      case EV_MSC: {
        if (rawEvent->code == MSC_SCAN) {
            mCurrentHidUsage = rawEvent->value;
        }
        break;
      }
      case EV_SYN: {
        if (rawEvent->code == SYN_REPORT) {
            mCurrentHidUsage = 0;
        }
      }
    }
  }
  void KeyboardInputMapper::processKey(){
    if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState,
       &keyCode, &keyMetaState, &policyFlags)) 
     
    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
    getListener()->notifyKey(&args);
  }
  InputListenerInterface* InputReader::ContextImpl::getListener() {
    return mReader->mQueuedListener.get();
  }
  
frameworks/native/services/inputflinger/InputListener.cpp
  void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
    mArgsQueue.push(new NotifyKeyArgs(*args));
  }
  void QueuedInputListener::flush() {
    size_t count = mArgsQueue.size();
    for (size_t i = 0; i < count; i++) {
      NotifyArgs* args = mArgsQueue[i];
      args->notify(mInnerListener);
    }
  }
  // 以 NotifyKeyArgs 为例
  void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
    listener->notifyKey(this);
    // InputReader 构造时,mQueuedListener = new QueuedInputListener(listener), listener 为 InputDispatcher
    // 所以到了 InputDispatcher 的 notifyKey 中
  }

5.EventHub

frameworks/native/services/inputflinger/EventHub.cpp
  EventHub::EventHub(void) :mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false), mNeedToScanDevices(true) {
    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
    mINotifyFd = inotify_init();
    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
    
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
    int wakeFds[2];
    result = pipe(wakeFds);
    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];
    
    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    
    eventItem.data.u32 = EPOLL_ID_WAKE;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
  }
  
  void EventHub::wake() {
    nWrite = write(mWakeWritePipeFd, "W", 1); //主线程,pipe[1]写入,InputReaderThread pipe[0]读取
  }

  // InputReaderThread 线程调用
  size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
    for (;;) {
      if (mNeedToScanDevices) {
        mNeedToScanDevices = false;
        scanDevicesLocked();
      }
      while (mOpeningDevices != NULL) {
        while (mPendingEventIndex < mPendingEventCount) {
          const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
          if (eventItem.data.u32 == EPOLL_ID_WAKE) {
 			do {
			  // 重要 InputReadThread 读取信息
			  nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
			} while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
          }
          
	      Device* device = mDevices.valueAt(deviceIndex);
		  if (eventItem.events & EPOLLIN) {
		    int32_t readSize = read(device->fd, readBuffer,
			sizeof(struct input_event) * capacity);
          }
      }
    }
    
    mLock.unlock(); // release lock before poll, must be before release_wake_lock
    release_wake_lock(WAKE_LOCK_ID);
    int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
    
    mPendingEventCount = size_t(pollResult);
    
    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
  }

6. 事件分发机制

Activity:
frameworks/base/core/java/android/app/Activity.java
  final void attach(Context context, ActivityThread aThread,){
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
  }
  public Window getWindow() {
    return mWindow;
  }
  
  public boolean dispatchTouchEvent(MotionEvent ev) {
    //ACTION_DOWN事件时,如果对应activity重写该方法,则调用对应方法
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
		onUserInteraction();
	}
	//PhoneWindow.superDispatchTouchEvent()
	if (getWindow().superDispatchTouchEvent(ev)) {
		return true;
	}

	return onTouchEvent(ev);
  }
  public boolean onTouchEvent(MotionEvent event) {
	if (mWindow.shouldCloseOnTouch(this, event)) {
		finish();
		return true;
	}
	return false;
  }

PhoneWindow:
frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
  private LayoutInflater mLayoutInflater;
  public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
  }// private DecorView mDecor;
 
DecorView:
frameworks/base/core/java/com/android/internal/policy/DecorView.java
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
  public boolean superDispatchTouchEvent(MotionEvent event) {
    return super.dispatchTouchEvent(event);
  }
}
//public class FrameLayout extends ViewGroup {}

ViewGroup:
frameworks/base/core/java/android/view/ViewGroup.java
public boolean dispatchTouchEvent(MotionEvent ev) {
  //判断窗口被遮挡,为true未遮挡继续 dispatch
  if (onFilterTouchEventForSecurity(ev)) {
	final int action = ev.getAction();
	final int actionMasked = action & MotionEvent.ACTION_MASK;
	// 初始化 down 动作,开始新的触摸手势时,放弃所有以前的状态。
    // 由于应用程序切换、ANR或某些其他状态更改,框架可能已放弃上一个手势的向上或取消事件。
    if (actionMasked == MotionEvent.ACTION_DOWN) {
	  cancelAndClearTouchTargets(ev);
	  resetTouchState();
    }
    if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
      final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
      // 进行拦截处理
      if (!disallowIntercept) {
        intercepted = onInterceptTouchEvent(ev);
        ev.setAction(action);
      }
    }
    final View[] children = mChildren;
    for (int i = childrenCount - 1; i >= 0; i--) {
      if (!canViewReceivePointerEvents(child)
	      || !isTransformedTouchPointInView(x, y, child, null)) {
		ev.setTargetAccessibilityFocus(false);
		continue;
	  }
      resetCancelNextUpFlag(child);
      if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) 
    }
  }
  
  if (mFirstTouchTarget == null) {
	// No touch targets so treat this as an ordinary view.
	handled = dispatchTransformedTouchEvent(ev, canceled, null,
			TouchTarget.ALL_POINTER_IDS);
  } else {
    TouchTarget target = mFirstTouchTarget;
    while (target != null) {
      final TouchTarget next = target.next;
	  if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
		handled = true;
	  }else {
	    if (dispatchTransformedTouchEvent(ev, cancelChild,
            target.child, target.pointerIdBits)) {
          handled = true;
        }
	  }
    }
  }
}

private boolean dispatchTransformedTouchEvent(){
  final int oldAction = event.getAction();
  if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
    event.setAction(MotionEvent.ACTION_CANCEL);
    if (child == null) {
	    handled = super.dispatchTouchEvent(event);
	} else {
		handled = child.dispatchTouchEvent(event);
	}
	event.setAction(oldAction);
	return handled;
  }
}

View:
frameworks/base/core/java/android/view/View.java
  public boolean dispatchTouchEvent(MotionEvent event) {
    if (onFilterTouchEventForSecurity(event)) {
      ListenerInfo li = mListenerInfo;
      if (li != null && li.mOnTouchListener != null /*View.setOnClickListener()*/
          && (mViewFlags & ENABLED_MASK) == ENABLED /*当前控件enabled状态*/
          && li.mOnTouchListener.onTouch(this, event)) {
          /*View.setOnClickListener()重写了onTouch()*/
        result = true;
      }
      if (!result && onTouchEvent(event)) {
		result = true;
	  }
    }
    return result;
  }
  public boolean dispatchTouchEvent(MotionEvent event) {
    onTouchEvent(event);
  }
  public boolean onTouchEvent(MotionEvent event) {
    final int action = event.getAction();
    switch (action) {
      case MotionEvent.ACTION_UP:
        mPerformClick = new PerformClick();
        break;
    }
  }
  private final class PerformClick implements Runnable {
    @Override
	public void run() {
		performClickInternal();
	}
  }
  private boolean performClickInternal() {
    notifyAutofillManagerOnClick();
    return performClick();
  }
  public boolean performClick() {
    final ListenerInfo li = mListenerInfo;
    if (li != null && li.mOnClickListener != null) {
      playSoundEffect(SoundEffectConstants.CLICK);
      li.mOnClickListener.onClick(this);
    }
    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
  }

  //在Button/TextView/Layout等 setOnClickListener(new View.OnClickListener(){})传入
  public void setOnClickListener(@Nullable OnClickListener l) {
	if (!isClickable()) {
		setClickable(true);
	}
    getListenerInfo().mOnClickListener = l;
  }  
  ListenerInfo getListenerInfo() {
    mListenerInfo = new ListenerInfo();
    return mListenerInfo;
  }

相关文章

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...