Chromium Mojo - 5

接着http://chromium.world/?id=1的“N. 后续逻辑”来。本文由@leonwxqian (各社交媒体同号)编写。


Mojo消息接受者注册时使用Dispatcher模式。

  1. 客户端向中间人注册一个回调(Event handler)

  2. 中间人检测到就绪状态,产生事件调用所有相关的回调

  3. 调用具体的工作类

中间人是一个不断循环的单独线程,它接受所有 handler 的注册,并负责查询状态,就绪后用指定的handler进行处理。类似于邮件的投递过程。


BlobRegistry为例。在RenderProcessHostImpl::RegisterMojoInterfaces处,

  registry->AddInterface(
      base::BindRepeating(&BlobRegistryWrapper::Bind,
                          storage_partition_impl_->GetBlobRegistry(), GetID()));

代码向service_manager::BinderRegistry*,registry注册了接口,绑定了BlobRegistryWrapper::Bind,this为storage_partition_impl_->GetBlobRegistry()即BlobRegistry*。

“中间人”即:service_manager::BinderRegistry

std::unique_ptr<storage::BlobRegistryImpl> blob_registry_;
void BlobRegistryWrapper::Bind(int process_id,  blink::mojom::BlobRegistryRequest request) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  blob_registry_->Bind(std::move(request), std::make_unique<BindingDelegate>(process_id));
}


其绑定的BlobRegistryRequest是mojo::InterfaceRequest<BlobRegistry>的语法糖。InterfaceRequest表示来自远程客户端的通过指定消息管道实现接口的请求。


回到Mojo消息的接受者处。mojo::InterfaceEndpointClient::HandleValidatedMessage的实现为MessageReceiver*,incoming_receiver_->AcceptWithResponder


BlobRegistryStub继承于mojo::MessageReceiverWithResponderStatus。因此,在 InterfacePtrState<T>::AcceptWithResponder --> InterfacePtrState<T>::ForwardMessageWithResponder进行消息转发后,由BlobRegistryStub首先收到消息。

收到消息后,经过如下路径传递:BlobRegistryStub::AcceptWithResponder --> BlobRegistryStubDispatch::AcceptWithResponder 

根据收到的不同消息类型(message->header()->name),BlobRegistryStubDispatch::AcceptWithResponder 会调用不同函数。

internal::kBlobRegistry_Register_Nameimpl->Register
internal::kBlobRegistry_RegisterFromStream_Nameimpl->RegisterFromStream
internal::kBlobRegistry_GetBlobFromUUID_Nameimpl->GetBlobFromUUID
internal::kBlobRegistry_URLStoreForOrigin_NameNOT REACHED

impl为storage::BlobRegistryImpl*即impl->Register为:storage::BlobRegistryImpl::Register


至此,程序正式地通过mojo调用到了客户端逻辑。


附:


MakeRequest会接受管道的一个handle,并创建一个InterfaceRequest<T>。


template <typename Interface>
InterfaceRequest<Interface> MakeRequest(
    InterfacePtr<Interface>* ptr,
    scoped_refptr<base::SequencedTaskRunner> runner = nullptr) {
  MessagePipe pipe;
  ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u),
            std::move(runner));
  return InterfaceRequest<Interface>(std::move(pipe.handle1));
}
// 类似上面的,只是绑定消息管道的一端到一个InterfacePtrInfo实例上。
template <typename Interface>
InterfaceRequest<Interface> MakeRequest(InterfacePtrInfo<Interface>* ptr_info) {
  MessagePipe pipe;
  ptr_info->set_handle(std::move(pipe.handle0));
  ptr_info->set_version(0u);
  return InterfaceRequest<Interface>(std::move(pipe.handle1));
}


----------------------------------------------------------------------------------------------------------------------

示例1:请求接口的远程实现。

给定以下接口:

   interface Database {
     OpenTable(Table& table);
   }

客户端的代码类似于以下代码:

   DatabasePtr database = ...;  // Connect to database.
   TablePtr table;
   database->OpenTable(MakeRequest(&table));

从MakeRequest返回后,|table|已准备好对其调用方法。


示例2:向远程服务注册本地实现。

给定以下接口。

Given the following interface
   interface Collector {
     RegisterSource(Source source);
   }

客户端的代码类似于以下代码:

   CollectorPtr collector = ...;  // Connect to Collector.
   SourcePtr source;
   InterfaceRequest<Source> source_request(&source);
   collector->RegisterSource(std::move(source));
   CreateSource(std::move(source_request));  // 在本地创建实现。