赞
踩
The top of a view hierarchy, implementing the needed protocol between View and the WindowManager. This is for the most part an internal implementation detail of WindowManagerGlobal. --google api 31
ViewRootImpl是视图结构的顶层,实现了视图和WM通信的协议。很大程度上是WindowManagerGlobal的内部实现细节。
ViewRootImpl不仅是视图和WM沟通的桥梁,也是事件分发的桥梁。
WindowManagerGlobal是单例模式,其中维护ViewRootImpl数组,每一个window对应一个ViewRootImpl,在添加View时会通过requestLayout注册Choreagrapher监听,等待系统下发绘制信号,触发View的绘制流程,也就是measure、layout、draw流程。
我们知道在绘制流程draw之后,应用的视图会显示在屏幕上,这中间需要通过wms拿到可在其上作画的画布。
在setView中会通过mWindowSession对象将window添加到wms,如下(只摘取关键代码):
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) { synchronized (this) { if (mView == null) { mView = view; // Schedule the first layout -before- adding to the window // manager, to make sure we do the relayout before receiving // any other events from the system. requestLayout(); res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), userId, mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets, mTempControls);
mWindowSession是什么?
This class represents an active client session. There is generally one Session object per process that is interacting with the window manager.
Session表示客户端和WMS交互的会话,每个进程都有一个Session对象与WMS交互。
看几个Session的成员方法:
@Override public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, InsetsState requestedVisibility, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls) { return mService.addWindow(this, window, attrs, viewVisibility, displayId, UserHandle.getUserId(mUid), requestedVisibility, outInputChannel, outInsetsState, outActiveControls); } @Override public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, int userId, InsetsState requestedVisibility, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls) { return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId, requestedVisibility, outInputChannel, outInsetsState, outActiveControls); } @Override public int addToDisplayWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, InsetsState outInsetsState) { return mService.addWindow(this, window, attrs, viewVisibility, displayId, UserHandle.getUserId(mUid), mDummyRequestedVisibility, null /* outInputChannel */, outInsetsState, mDummyControls); } @Override public void remove(IWindow window) { mService.removeWindow(this, window); } @Override public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) { mService.setWillReplaceWindows(appToken, childrenOnly); }
最终都是在和WMS打交道。
在创建ViewRootImple对象时,默认调用WindowManagerGlobal的静态方法getWindowSession,获取WMS本地代理对象,调用WMS的openSession方法创建Session对象,流程如下:
由前文我们知道ViewRootImple在setView时会注册Choreographer的监听,等下次系统下发绘制同步信号时,ViewRootImpl执行performTraversals方法,其中有这样一行代码:
if (mFirst || windowShouldResize || viewVisibilityChanged || params != null
|| mForceNextWindowRelayout) {
...省略
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...省略
}
其中会调用Session对象的relayout方法:
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
...省略
int relayoutResult = mWindowSession.relayout(mWindow, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize);
...省略
Session对象调用WMS的relayout方法:
@Override
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
int res = mService.relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSurfaceSize);
return res;
}
WMS调用自身的createSurfaceControl方法:
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
...省略
// Create surfaceControl before surface placement otherwise layout will be skipped
// (because WS.isGoneForLayout() is true when there is no surface.
if (shouldRelayout) {
try {
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
} catch (Exception e) {
...省略
}
}
接着调用WindowStateAnimator的createSurfaceLocked方法:
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
WindowSurfaceController surfaceController;
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
在WindowStateAnimator的createSurfaceLocked方法中创建WindowSurfaceController对象并返回WindowSurfaceController对象:
WindowSurfaceController createSurfaceLocked(int windowType) {
...省略
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
height, format, flags, this, windowType);
...省略
WindowSurfaceController在构造函数中创建SurfaceControl对象:
WindowSurfaceController(String name, int w, int h, int format, int flags, WindowStateAnimator animator, int windowType) { ...省略 final SurfaceControl.Builder b = win.makeSurface() .setParent(win.getSurfaceControl()) .setName(name) .setBufferSize(w, h) .setFormat(format) .setFlags(flags) .setMetadata(METADATA_WINDOW_TYPE, windowType) .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid) .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid) .setCallsite("WindowSurfaceController"); ...省略 mSurfaceControl = b.build(); } @NonNull public SurfaceControl build() { ...省略 return new SurfaceControl( mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, mLocalOwnerView, mCallsite); }
在SurfaceControl构造函数中调用了本地方法nativeCreate:
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, String callsite) throws OutOfResourcesException, IllegalArgumentException { ...省略 try { if (metadata != null && metadata.size() > 0) { metaParcel.writeInt(metadata.size()); for (int i = 0; i < metadata.size(); ++i) { metaParcel.writeInt(metadata.keyAt(i)); metaParcel.writeByteArray( ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()) .putInt(metadata.valueAt(i)).array()); } metaParcel.setDataPosition(0); } mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel); } finally { metaParcel.recycle(); } ...省略 }
到这里由java层转至native层,先总结下java层的流程:
nativeCreate返回的就是画布的底层指针,保存在SurfaceControl中,java层后续的操作都是基于这个指针操作画布。
接着来看native层的创建流程:
frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,401 jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject, 402 jobject metadataParcel) { 403 ScopedUtfChars name(env, nameStr); 404 sp<SurfaceComposerClient> client; 405 if (sessionObj != NULL) { 406 client = android_view_SurfaceSession_getClient(env, sessionObj); 407 } else { 408 client = SurfaceComposerClient::getDefault(); 409 } 410 SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject); 411 sp<SurfaceControl> surface; 412 LayerMetadata metadata; 413 Parcel* parcel = parcelForJavaObject(env, metadataParcel); 414 if (parcel && !parcel->objectsCount()) { 415 status_t err = metadata.readFromParcel(parcel); 416 if (err != NO_ERROR) { 417 jniThrowException(env, "java/lang/IllegalArgumentException", 418 "Metadata parcel has wrong format"); 419 } 420 } 421 422 sp<IBinder> parentHandle; 423 if (parent != nullptr) { 424 parentHandle = parent->getHandle(); 425 } 426 427 status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, 428 flags, parentHandle, std::move(metadata)); 429 if (err == NAME_NOT_FOUND) { 430 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 431 return 0; 432 } else if (err != NO_ERROR) { 433 jniThrowException(env, OutOfResourcesException, statusToString(err).c_str()); 434 return 0; 435 } 436 437 surface->incStrong((void *)nativeCreate); 438 return reinterpret_cast<jlong>(surface.get()); 439 }
这里会创建SurfaceComposerClient、SurfaceControl和Surface,这三件套。
看下SurfaceComposerClient的createSurfaceChecked方法:
路径:/framework/native/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h, 2376 PixelFormat format, 2377 sp<SurfaceControl>* outSurface, int32_t flags, 2378 const sp<IBinder>& parentHandle, 2379 LayerMetadata metadata, 2380 uint32_t* outTransformHint) { 2381 sp<SurfaceControl> sur; 2382 status_t err = mStatus; 2383 2384 if (mStatus == NO_ERROR) { 2385 gui::CreateSurfaceResult result; 2386 binder::Status status = mClient->createSurface(std::string(name.string()), flags, 2387 parentHandle, std::move(metadata), &result); 2388 err = statusTFromBinderStatus(status); 2389 if (outTransformHint) { 2390 *outTransformHint = result.transformHint; 2391 } 2392 ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); 2393 if (err == NO_ERROR) { 2394 *outSurface = new SurfaceControl(this, result.handle, result.layerId, 2395 toString(result.layerName), w, h, format, 2396 result.transformHint, flags); 2397 } 2398 } 2399 return err; 2400 }
这里先调用mClient对象创建Surface,然后将创建结果作为参数创建SurfaceControl对象,并赋值给入参出参的outSurface指针。接下来看下Client的createSurface方法。
路径:/frameworks/native/services/surfaceflinger/Client.cpp
63 binder::Status Client::createSurface(const std::string& name, int32_t flags,
64 const sp<IBinder>& parent, const gui::LayerMetadata& metadata,
65 gui::CreateSurfaceResult* outResult) {
66 // We rely on createLayer to check permissions.67 sp<IBinder> handle;
68 LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this), name.c_str(),
69 static_cast<uint32_t>(flags), std::move(metadata));
70 args.parentHandle = parent;
71 const status_t status = mFlinger->createLayer(args, *outResult);
72 return binderStatusFromStatusT(status);
73 }
调用mFlinger对象的createlayer方法,这里的mFlinger对象是什么呢?
路径:/frameworks/native/services/surfaceflinger/Client.h
private: 46 // ISurfaceComposerClient interface 47 48 binder::Status createSurface(const std::string& name, int32_t flags, const sp<IBinder>& parent, 49 const gui::LayerMetadata& metadata, 50 gui::CreateSurfaceResult* outResult) override; 51 52 binder::Status clearLayerFrameStats(const sp<IBinder>& handle) override; 53 54 binder::Status getLayerFrameStats(const sp<IBinder>& handle, 55 gui::FrameStats* outStats) override; 56 57 binder::Status mirrorSurface(const sp<IBinder>& mirrorFromHandle, 58 gui::CreateSurfaceResult* outResult) override; 59 60 binder::Status mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult* outResult) override; 61 62 // constant 63 sp<SurfaceFlinger> mFlinger;
mFlinger就是SurfaceFlinger的指针。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
6215 status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult) { 6216 status_t result = NO_ERROR; 6217 6218 sp<Layer> layer; 6219 6220 switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) { 6221 case ISurfaceComposerClient::eFXSurfaceBufferQueue: 6222 case ISurfaceComposerClient::eFXSurfaceContainer: 6223 case ISurfaceComposerClient::eFXSurfaceBufferState: 6224 args.flags |= ISurfaceComposerClient::eNoColorFill; 6225 FMT_FALLTHROUGH; 6226 case ISurfaceComposerClient::eFXSurfaceEffect: { 6227 result = createBufferStateLayer(args, &outResult.handle, &layer); 6228 std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter(); 6229 if (pendingBufferCounter) { 6230 std::string counterName = layer->getPendingBufferCounterName(); 6231 mBufferCountTracker.add(outResult.handle->localBinder(), counterName, 6232 pendingBufferCounter); 6233 #ifdef MTK_SF_DEBUG_SUPPORT 6234 mLayerTracker.track(layer->getName(), android::base::StringPrintf("%s,%d", __func__, __LINE__)); 6235 #endif 6236 } 6237 #ifdef MTK_SF_MSYNC 6238 if (mMSyncSfApi && result == NO_ERROR) { 6239 mMSyncSfApi->registerLayer(layer.get()); 6240 } 6241 #endif 6242 } break; 6243 default: 6244 result = BAD_VALUE; 6245 break; 6246 } 6247 6248 if (result != NO_ERROR) { 6249 return result; 6250 } 6251 6252 args.addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess(); 6253 // We can safely promote the parent layer in binder thread because we have a strong reference6254 // to the layer's handle inside this scope.6255 sp<Layer> parent = LayerHandle::getLayer(args.parentHandle.promote()); 6256 if (args.parentHandle != nullptr && parent == nullptr) { 6257 ALOGE("Invalid parent handle %p", args.parentHandle.promote().get()); 6258 args.addToRoot = false; 6259 } 6260 6261 uint32_t outTransformHint; 6262 result = addClientLayer(args, outResult.handle, layer, parent, &outTransformHint); 6263 if (result != NO_ERROR) { 6264 return result; 6265 } 6266 6267 outResult.transformHint = static_cast<int32_t>(outTransformHint); 6268 outResult.layerId = layer->sequence; 6269 outResult.layerName = String16(layer->getDebugName()); 6270 return result; 6271 }
这里就是根据标志创建不同的layer,layer就是Surface合成图层的基本单位了。创建的图层注册添加到SurfaceFlinger,并向上保存到SurfaceContral对象当中,并把指针返回到java层,完成画布的创建。
setView中会创建WindowInputEventReceiver,在构造方法中会把WindowInputEventReceiver注册到系统层的事件分发流程:
public InputEventReceiver(InputChannel inputChannel, Looper looper) {
if (inputChannel == null) {
throw new IllegalArgumentException("inputChannel must not be null");
}
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
mInputChannel = inputChannel;
mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference<InputEventReceiver>(this),
inputChannel, mMessageQueue);
mCloseGuard.open("dispose");
}
路径:/frameworks/base/core/jni/android_view_InputEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, 529 jobject inputChannelObj, jobject messageQueueObj) { 530 std::shared_ptr<InputChannel> inputChannel = 531 android_view_InputChannel_getInputChannel(env, inputChannelObj); 532 if (inputChannel == nullptr) { 533 jniThrowRuntimeException(env, "InputChannel is not initialized."); 534 return 0; 535 } 536 537 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 538 if (messageQueue == nullptr) { 539 jniThrowRuntimeException(env, "MessageQueue is not initialized."); 540 return 0; 541 } 542 543 sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env, 544 receiverWeak, inputChannel, messageQueue); 545 status_t status = receiver->initialize(); 546 if (status) { 547 std::string message = android::base:: 548 StringPrintf("Failed to initialize input event receiver. status=%s(%d)", 549 statusToString(status).c_str(), status); 550 jniThrowRuntimeException(env, message.c_str()); 551 return 0; 552 } 553 554 receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object555 return reinterpret_cast<jlong>(receiver.get()); 556 }
这里会基于java层传入的参数创建native层的receiver,后续通过reveiver分发事件到java层
326 status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,327 bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) { 328 ...省略 478 env->CallVoidMethod(receiverObj.get(), 479 gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); 480 if (env->ExceptionCheck()) { 481 ALOGE("Exception dispatching input event."); 482 skipCallbacks = true; 483 } 484 env->DeleteLocalRef(inputEventObj); 485 } else { 486 ALOGW("channel '%s' ~ Failed to obtain event object.", 487 getInputChannelName().c_str()); 488 skipCallbacks = true; 489 } 490 } 491 } 492 }
这里通过反射调用java层的dispatchInputEvent方法把时间分发到java层,事件进入WindowInputEventReceiver的onInputEvent方法。后续流转顺序:onInputEvent-》enqueueInputEvent-》doProcessInputEvents-》deliverInputEvent-》进入InputStage
InputState采用责任链模式,进行事件的流转,责任链组装过程:
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);
触摸事件的分发流程:mSyntheticInputStage --> viewPostImeStage
通过在在view分发事件方法processPointerEvent中添加trace,
private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; boolean handled = mHandwritingInitiator.onTouchEvent(event); mAttachInfo.mUnbufferedDispatchRequested = false; mAttachInfo.mHandlingPointerEvent = true; //@ M: control the flag when input move and up BoostFwkFactory.getInstance().makeBoostFwkManager().perfHint( mScrollScenario.setAction(BoostFwkManager.Scroll.INPUT_EVENT) .setBoostStatus(BoostFwkManager.BOOST_BEGIN) .setMotionEvent(event) .setContext(mContext) ); //@ M: End of input control // If the event was fully handled by the handwriting initiator, then don't dispatch it // to the view tree. handled = handled || mView.dispatchPointerEvent(event); //if (handled && ViewDebugManager.DEBUG_ENG) { if (handled) { Log.v(mTag, "App handle pointer event: event = " + event + ", mView = " + mView + ", this = " + this, new Throwable()); }
可以看到触摸事件在责任链上的流转过程:
到这里事件流转到mView中,mView就是DecorView
/DecorView.java
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Window.Callback cb = mWindow.getCallback();
return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
}
这里拿到的callback就是activity,事件流转到activity,后边就是大家熟悉的视图层的事件流转过程了。
总结下:
ViewRootImpl作为桥梁注册事件监听,底层事件先分发到ViewRootImpl,再分发到视图层。
系统事件分发到WindowInputEventReceiver,进入onInputEvent方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。