IMS:InputChannel通过socket发送Input给App
IMS:InputChannel通過socket發(fā)送Input給App
android11-release
IMS:InputManagerService啟動簡要
IMS:InputReader線程獲取輸入事件
IMS:InputDispatcher線程分發(fā)事件
InputChannel監(jiān)聽
??IMS與WMS強(qiáng)相關(guān),這個InputChannel就是在addView時是聲明。APP就是在Activity.java中setContentView(),經(jīng)過AMS與WMS之間交互,這里不過多介紹,最終 WindowManagerImpl.addView() 內(nèi)部再調(diào)用 WindowManagerGlobal.addView()。
添加App的View
frameworks/base/core/java/android/view/WindowManagerGlobal.java frameworks/base/core/java/android/view/ViewRootImpl.java public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,int userId) {synchronized (this) {if (mView == null) {// ... ... ... ...InputChannel inputChannel = null;if ((mWindowAttributes.inputFeatures& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {inputChannel = new InputChannel();}// ... ... ... ...try {mOrigWindowType = mWindowAttributes.type;mAttachInfo.mRecomputeGlobalAttributes = true;collectViewAttributes();adjustLayoutParamsForCompatibility(mWindowAttributes);res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mDisplayCutout, inputChannel,mTempInsets, mTempControls);setFrame(mTmpFrame);} catch (RemoteException e) {// ... ... ... ...if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);// ... ... ... ...if (inputChannel != null) {if (mInputQueueCallback != null) {mInputQueue = new InputQueue();mInputQueueCallback.onInputQueueCreated(mInputQueue);}mInputEventReceiver = new WindowInputEventReceiver(inputChannel,Looper.myLooper());}// ... ... ... ...// Set up the input pipeline.CharSequence counterSuffix = attrs.getTitle();mSyntheticInputStage = new SyntheticInputStage();InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,"aq:native-post-ime:" + counterSuffix);InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);InputStage imeStage = new ImeInputStage(earlyPostImeStage,"aq:ime:" + counterSuffix);InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,"aq:native-pre-ime:" + counterSuffix);mFirstInputStage = nativePreImeStage;mFirstPostImeInputStage = earlyPostImeStage;mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;// ... ... ... ...}}}- 1、InputChannel 初始化工作
- 2、mWindowSession.addToDisplayAsUser 通過Binder調(diào)用,進(jìn)入system進(jìn)程的Session。這里最終構(gòu)建(server)、(client)的InputChannel。
- 3、WindowInputEventReceiver 接收器初始化
- 4、InputStage 責(zé)任鏈調(diào)用
構(gòu)建(server)、(client)的InputChannel
frameworks/base/services/core/java/com/android/server/wm/Session.java frameworks/services/core/java/com/android/server/wm/WindowManagerService.java frameworks/services/core/java/com/android/server/wm/WindowState.java frameworks/base/core/java/android/view/InputChannel.java frameworks/base/core/jni/android_view_InputChannel.cpp frameworks/native/libs/input/InputTransport.cpp public int addWindow(Session session, IWindow client, int seq,LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,Rect outContentInsets, Rect outStableInsets,DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,int requestUserId) {// ... ... ... ...final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid, userId,session.mCanAddInternalSystemWindow);// ... ... ... ...final boolean openInputChannels = (outInputChannel != null&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);if (openInputChannels) {win.openInputChannel(outInputChannel);}// ... ... ... ...}- inputChannels[0] 所對應(yīng) (server) 的 InputChannel ,保存到 mInputChannel;并添加 Connection ,“InputDispatcher” 線程的 Looper 添加對 socket 服務(wù)端的監(jiān)聽
- inputChannels[1] 所對應(yīng) (client) 的 InputChannel ,傳遞給 outInputChannel,最終傳遞給 ViewRootImpl 的 mInputChannel
WindowInputEventReceiver接收器初始化
frameworks/base/core/java/android/view/ViewRootImpl.java frameworks/base/core/java/android/view/InputEventReceiver.java frameworks/base/core/jni/android_view_InputEventReceiver.cpp
receiver->initialize()初始化設(shè)置setFdEvents,這里 handler/Looper 輪詢回調(diào) LooperCallback,POLL_CALLBACK某個被監(jiān)聽 fd 被觸發(fā)回調(diào)response.request.callback->handleEvent(fd, events, data);
InputStage 責(zé)任鏈調(diào)用
frameworks/base/core/java/android/view/ViewRootImpl.javaInputStage初始化,Input 事件傳遞過來會調(diào)用 InputStage.deliver,通過責(zé)任鏈模式執(zhí)行
InputChannel通過socket發(fā)送Input給App
?? 通過上邊了解相關(guān)的前期工作,接著 IMS:InputDispatcher線程分發(fā)事件 經(jīng)過 InputChannel 通過 socket 向遠(yuǎn)端的socket發(fā)送消息給Window。
監(jiān)聽 fd 回調(diào) LooperCallback
::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); LooperCallback 回調(diào)到 handleEvent
frameworks/base/core/jni/android_view_InputEventReceiver.cpp frameworks/base/core/java/android/view/InputChannel.java frameworks/base/core/java/android/view/ViewRootImpl.java
最終走到WindowInputEventReceiver的onInputEvent,通過enqueueInputEvent -> doProcessInputEvents -> deliverInputEvent -> stage.deliver(q)調(diào)用執(zhí)行InputStage 責(zé)任鏈
InputStage的各子類Input事件onProcess處理
查看父類InputStage主要result = onProcess(q)處理Input事件,apply->forward->onDeliverToNext->mNext.deliver處理責(zé)任鏈傳遞或finish。
例如ViewPostImeInputStage中processKeyEvent
mView.dispatchKeyEvent(event)事件發(fā)送到App界面,這里mView就是DecorView,涉及PhoneWindow.java、DecorView.java
這里handled可以判斷應(yīng)用是否攔截KeyEvent事件,但是需要明白的是不管應(yīng)用攔不攔截,Input事件都已經(jīng)發(fā)送給應(yīng)用了。
Activity回調(diào)Callback
frameworks/base/core/java/android/app/Activity.java frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java frameworks/base/core/java/com/android/internal/policy/DecorView.java
cb.dispatchKeyEvent(event) 這個Window.Callback是Activity回調(diào)注冊
總結(jié)
以上是生活随笔為你收集整理的IMS:InputChannel通过socket发送Input给App的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Supermemo背单词6周年了
- 下一篇: 【POJ 3580】 SuperMemo