Brillo开发: system/webservd代码分析 – webservd – D-Bus service

webservd(system/webservd/webservd)提供了两个D-Bus service: ProtocolHandler与Server,包含一个D-Bus service配置文件和两个接口配置文件:

  1. system/webservd/webservd/dbus_bindings/dbus-service-config.json – 配置文件
  2. system/webservd/webservd/dbus_bindings/org.chromium.WebServer.ProtocolHandler.dbus-xml – ProtocolHandler 接口定义
  3. system/webservd/webservd/dbus_bindings/org.chromium.WebServer.Server.dbus-xml – Server接口定义

  • dbus-service-config.json – 接口配置
{
  "service_name": "org.chromium.WebServer",
  "object_manager": {
    "name": "org.chromium.WebServer.ObjectManager",
    "object_path": "/org/chromium/WebServer"
  }
}

定义了service name: org.chromium.WebService; object manager的name: org.chromium.WebServer.ObjectManager, path为/org/chromium/WebServer。

  • org.chromium.WebServer.ProtocolHandler.dbus-xml

文件内容如下:

<node xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <interface name="org.chromium.WebServer.ProtocolHandler">
    <!-- Methods -->
    <method name="AddRequestHandler">
      <tp:docstring>
        Adds a handler for the given |url|, and optionally request |method|.
        On success returns a handler ID.
      </tp:docstring>
      <arg name="url" type="s" direction="in"/>
      <arg name="method" type="s" direction="in"/>
      <arg name="service_name" type="s" direction="in"/>
      <arg name="request_handler_id" type="s" direction="out"/>
      <annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
      <annotation name="org.chromium.DBus.Method.IncludeDBusMessage"
                  value="true"/>
    </method>
    <method name="RemoveRequestHandler">
      <tp:docstring>
        Removes a previously registered request handler.
        The |handler_id| is the ID returned from AddHanlder() method.
      </tp:docstring>
      <arg name="request_handler_id" type="s" direction="in"/>
      <annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
    </method>
    <method name="GetRequestFileData">
      <tp:docstring>
        Returns the contents of the given uploaded file. The |file_id| parameter
        must correspond to the file_id member of FileInfo structure returned
        by |Files| property for the given |request_id|.
      </tp:docstring>
      <arg name="request_id" type="s" direction="in"/>
      <arg name="file_id" type="i" direction="in"/>
      <arg name="contents" type="h" direction="out"/>
      <annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
    </method>
    <method name="CompleteRequest">
      <tp:docstring>
        Fulfills the request with specified |request_id| and provides response.
        |data_size| if the size of the data is known. Otherwise should be set to
        a value of -1. The actual data is to be written to the pipe provided
        in |response_stream| file descriptor.
      </tp:docstring>
      <arg name="request_id" type="s" direction="in"/>
      <arg name="status_code" type="i" direction="in"/>
      <arg name="headers" type="a(ss)" direction="in"/>
      <arg name="data_size" type="x" direction="in"/>
      <arg name="response_stream" type="h" direction="out"/>
      <annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
    </method>
    <!-- Properties -->
    <property name="Id" type="s" access="read">
      <tp:docstring>
        Returns a unique ID of this instance.
      </tp:docstring>
    </property>
    <property name="Name" type="s" access="read">
      <tp:docstring>
        Returns the name of the handler. Multiple related protocol handler
        could share the same name so that clients don't have to register
        request handlers for each of them separately.
      </tp:docstring>
    </property>
    <property name="Port" type="q" access="read">
      <tp:docstring>
        Returns the port number this instance is serving requests on.
      </tp:docstring>
    </property>
    <property name="Protocol" type="s" access="read">
      <tp:docstring>
        Returns the protocol name of this instance ("http" or "https").
      </tp:docstring>
    </property>
    <property name="CertificateFingerprint" type="ay" access="read">
      <tp:docstring>
        Returns the TLS certificate fingerprint used for HTTPS instance or
        empty array if this is an unsecured HTTP instance.
      </tp:docstring>
    </property>
  </interface>
</node>

可以看到这个接口提供如下方法:

  1. AddRequestHandler(url, method, service_name)
  2. RemoveRequestHandlere(request_handler_id)
  3. GetRequestFileData(request_id, file_id)
  4. CompleteRequest(request_id, status_code, headers, data_size)

同时还包含如下properties:

  1. Id
  2. Name
  3. Port
  4. Protocol
  5. CertificateFingerprint
  • org.chromium.WebServer.Server.dbus-xml

文件内容如下:

<node name="/org/chromium/WebServer/Server"
      xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <interface name="org.chromium.WebServer.Server">
    <!-- Methods -->
    <method name="Ping">
      <arg name="message" type="s" direction="out"/>
      <annotation name="org.chromium.DBus.Method.Kind" value="simple"/>
    </method>
    <property name="DefaultRequestTimeout" type="i" access="read">
      <tp:docstring>
        Default timeout (in seconds) for request.
      </tp:docstring>
    </property>
  </interface>
</node>

可以看到这个接口提供如下方法:

  1. Ping()

同时还包含如下properties:

  1. DefaultRequestTimeout
  • 编译

webservd作为server端,编译出来的:

生成adapter(service端)的头文件:

[ 10% 6/60] /bin/bash -c "(true) && (mkdir -p out/target/product/rpi/gen/EXECUTABLES/webservd_intermediates/dbus_bindings/dbus_bindings/) && (out/host/linux-x86/bin/dbus-binding-generator --service-config=system/webservd/webservd/dbus_bindings/dbus-service-config.json --adaptor=out/target/product/rpi/gen/EXECUTABLES/webservd_intermediates/dbus_bindings/dbus_bindings/org.chromium.WebServer.ProtocolHandler.h system/webservd/webservd/dbus_bindings/org.chromium.WebServer.ProtocolHandler.dbus-xml)"
[ 11% 7/60] /bin/bash -c "(true) && (mkdir -p out/target/product/rpi/gen/EXECUTABLES/webservd_intermediates/dbus_bindings/dbus_bindings/) && (out/host/linux-x86/bin/dbus-binding-generator --service-config=system/webservd/webservd/dbus_bindings/dbus-service-config.json --adaptor=out/target/product/rpi/gen/EXECUTABLES/webservd_intermediates/dbus_bindings/dbus_bindings/org.chromium.WebServer.Server.h system/webservd/webservd/dbus_bindings/org.chromium.WebServer.Server.dbus-xml)"

可见:

dbus-service-config.json + org.chromium.WebServer.ProtocolHandler.dbus-xml -> org.chromium.WebServer.ProtocolHandler.h

dbus-service-config.json + org.chromium.WebServer.Server.dbus-xml -> org.chromium.WebServer.Server.h

而dbus-binding-generator相关的代码在external/dbus-binding-generator。

namespace org {
namespace chromium {
namespace WebServer {

// Interface definition for org::chromium::WebServer::Server.
class ServerInterface {
 public:
  virtual ~ServerInterface() = default;

  virtual std::string Ping() = 0;
};

// Interface adaptor for org::chromium::WebServer::Server.
class ServerAdaptor {
 public:
  ServerAdaptor(ServerInterface* interface) : interface_(interface) {}

  void RegisterWithDBusObject(brillo::dbus_utils::DBusObject* object) {
    brillo::dbus_utils::DBusInterface* itf =
        object->AddOrGetInterface("org.chromium.WebServer.Server");

    itf->AddSimpleMethodHandler(
        "Ping",
        base::Unretained(interface_),
        &ServerInterface::Ping);

    itf->AddProperty(DefaultRequestTimeoutName(), &default_request_timeout_);
  }

  // Default timeout (in seconds) for request.
  static const char* DefaultRequestTimeoutName() { return "DefaultRequestTimeout"; }
  int32_t GetDefaultRequestTimeout() const {
    return default_request_timeout_.GetValue().Get<int32_t>();
  }
  void SetDefaultRequestTimeout(int32_t default_request_timeout) {
    default_request_timeout_.SetValue(default_request_timeout);
  }

  static dbus::ObjectPath GetObjectPath() {
    return dbus::ObjectPath{"/org/chromium/WebServer/Server"};
  }

 private:
  brillo::dbus_utils::ExportedProperty<int32_t> default_request_timeout_;

  ServerInterface* interface_;  // Owned by container of this adapter.

  DISALLOW_COPY_AND_ASSIGN(ServerAdaptor);
};

}  // namespace WebServer
}  // namespace chromium
}  // namespace org

生成proxy(client端)的头文件:

[ 35% 21/60] /bin/bash -c "(true) && (mkdir -p out/target/product/rpi/gen/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/dbus_bindings/include/webservd/) && (out/host/linux-x86/bin/dbus-binding-generator --service-config=system/webservd/webservd/dbus_bindings/dbus-service-config.json --proxy=out/target/product/rpi/gen/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/dbus_bindings/include/webservd/dbus-proxies.h system/webservd/webservd/dbus_bindings/org.chromium.WebServer.ProtocolHandler.dbus-xml system/webservd/webservd/dbus_bindings/org.chromium.WebServer.Server.dbus-xml)"

有兴趣看一下dbus-proxies.h(org::chromium::WebServer::Server部分):

namespace org {
namespace chromium {
namespace WebServer {

// Abstract interface proxy for org::chromium::WebServer::Server.
class ServerProxyInterface {
 public:
  virtual ~ServerProxyInterface() = default;

  virtual bool Ping(
      std::string* out_message,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void PingAsync(
      const base::Callback<void(const std::string& /*message*/)>& success_callback,
      const base::Callback<void(brillo::Error*)>& error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  static const char* DefaultRequestTimeoutName() { return "DefaultRequestTimeout"; }
  virtual int32_t default_request_timeout() const = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;

  virtual void SetPropertyChangedCallback(
      const base::Callback<void(ServerProxyInterface*, const std::string&)>& callback) = 0;
};

}  // namespace WebServer
}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {
namespace WebServer {

// Interface proxy for org::chromium::WebServer::Server.
class ServerProxy final : public ServerProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.WebServer.Server",
                            callback} {
      RegisterProperty(DefaultRequestTimeoutName(), &default_request_timeout);
    }

    brillo::dbus_utils::Property<int32_t> default_request_timeout;

   private:
    DISALLOW_COPY_AND_ASSIGN(PropertySet);
  };

  ServerProxy(
      const scoped_refptr<dbus::Bus>& bus,
      PropertySet* property_set) :
          bus_{bus},
          property_set_{property_set},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  ~ServerProxy() override {
  }

  void ReleaseObjectProxy(const base::Closure& callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, callback);
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }

  void SetPropertyChangedCallback(
      const base::Callback<void(ServerProxyInterface*, const std::string&)>& callback) override {
    on_property_changed_ = callback;
  }

  const PropertySet* GetProperties() const { return property_set_; }
  PropertySet* GetProperties() { return property_set_; }

  bool Ping(
      std::string* out_message,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.WebServer.Server",
        "Ping",
        error);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_message);
  }

  void PingAsync(
      const base::Callback<void(const std::string& /*message*/)>& success_callback,
      const base::Callback<void(brillo::Error*)>& error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.WebServer.Server",
        "Ping",
        success_callback,
        error_callback);
  }

  int32_t default_request_timeout() const override {
    return property_set_->default_request_timeout.value();
  }

 private:
  void OnPropertyChanged(const std::string& property_name) {
    if (!on_property_changed_.is_null())
      on_property_changed_.Run(this, property_name);
  }

  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.WebServer"};
  const dbus::ObjectPath object_path_{"/org/chromium/WebServer/Server"};
  PropertySet* property_set_;
  base::Callback<void(ServerProxyInterface*, const std::string&)> on_property_changed_;
  dbus::ObjectProxy* dbus_object_proxy_;

  friend class org::chromium::WebServer::ObjectManagerProxy;
  DISALLOW_COPY_AND_ASSIGN(ServerProxy);
};

}  // namespace WebServer
}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {
namespace WebServer {

class ObjectManagerProxy : public dbus::ObjectManager::Interface {
 public:
  ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus)
      : bus_{bus},
        dbus_object_manager_{bus->GetObjectManager(
            "org.chromium.WebServer",
            dbus::ObjectPath{"/org/chromium/WebServer"})} {
    dbus_object_manager_->RegisterInterface("org.chromium.WebServer.ProtocolHandler", this);
    dbus_object_manager_->RegisterInterface("org.chromium.WebServer.Server", this);
  }

  ~ObjectManagerProxy() override {
    dbus_object_manager_->UnregisterInterface("org.chromium.WebServer.ProtocolHandler");
    dbus_object_manager_->UnregisterInterface("org.chromium.WebServer.Server");
  }

  dbus::ObjectManager* GetObjectManagerProxy() const {
    return dbus_object_manager_;
  }

  org::chromium::WebServer::ProtocolHandlerProxyInterface* GetProtocolHandlerProxy(
      const dbus::ObjectPath& object_path) {
    auto p = protocol_handler_instances_.find(object_path);
    if (p != protocol_handler_instances_.end())
      return p->second.get();
    return nullptr;
  }
  std::vector<org::chromium::WebServer::ProtocolHandlerProxyInterface*> GetProtocolHandlerInstances() const {
    std::vector<org::chromium::WebServer::ProtocolHandlerProxyInterface*> values;
    values.reserve(protocol_handler_instances_.size());
    for (const auto& pair : protocol_handler_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetProtocolHandlerAddedCallback(
      const base::Callback<void(org::chromium::WebServer::ProtocolHandlerProxyInterface*)>& callback) {
    on_protocol_handler_added_ = callback;
  }
  void SetProtocolHandlerRemovedCallback(
      const base::Callback<void(const dbus::ObjectPath&)>& callback) {
    on_protocol_handler_removed_ = callback;
  }

  org::chromium::WebServer::ServerProxyInterface* GetServerProxy() {
    if (server_instances_.empty())
      return nullptr;
    return server_instances_.begin()->second.get();
  }
  std::vector<org::chromium::WebServer::ServerProxyInterface*> GetServerInstances() const {
    std::vector<org::chromium::WebServer::ServerProxyInterface*> values;
    values.reserve(server_instances_.size());
    for (const auto& pair : server_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetServerAddedCallback(
      const base::Callback<void(org::chromium::WebServer::ServerProxyInterface*)>& callback) {
    on_server_added_ = callback;
  }
  void SetServerRemovedCallback(
      const base::Callback<void(const dbus::ObjectPath&)>& callback) {
    on_server_removed_ = callback;
  }

 private:
  void OnPropertyChanged(const dbus::ObjectPath& object_path,
                         const std::string& interface_name,
                         const std::string& property_name) {
    if (interface_name == "org.chromium.WebServer.ProtocolHandler") {
      auto p = protocol_handler_instances_.find(object_path);
      if (p == protocol_handler_instances_.end())
        return;
      p->second->OnPropertyChanged(property_name);
      return;
    }
    if (interface_name == "org.chromium.WebServer.Server") {
      auto p = server_instances_.find(object_path);
      if (p == server_instances_.end())
        return;
      p->second->OnPropertyChanged(property_name);
      return;
    }
  }

  void ObjectAdded(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.WebServer.ProtocolHandler") {
      auto property_set =
          static_cast<org::chromium::WebServer::ProtocolHandlerProxy::PropertySet*>(
              dbus_object_manager_->GetProperties(object_path, interface_name));
      std::unique_ptr<org::chromium::WebServer::ProtocolHandlerProxy> protocol_handler_proxy{
        new org::chromium::WebServer::ProtocolHandlerProxy{bus_, object_path, property_set}
      };
      auto p = protocol_handler_instances_.emplace(object_path, std::move(protocol_handler_proxy));
      if (!on_protocol_handler_added_.is_null())
        on_protocol_handler_added_.Run(p.first->second.get());
      return;
    }
    if (interface_name == "org.chromium.WebServer.Server") {
      auto property_set =
          static_cast<org::chromium::WebServer::ServerProxy::PropertySet*>(
              dbus_object_manager_->GetProperties(object_path, interface_name));
      std::unique_ptr<org::chromium::WebServer::ServerProxy> server_proxy{
        new org::chromium::WebServer::ServerProxy{bus_, property_set}
      };
      auto p = server_instances_.emplace(object_path, std::move(server_proxy));
      if (!on_server_added_.is_null())
        on_server_added_.Run(p.first->second.get());
      return;
    }
  }

  void ObjectRemoved(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.WebServer.ProtocolHandler") {
      auto p = protocol_handler_instances_.find(object_path);
      if (p != protocol_handler_instances_.end()) {
        if (!on_protocol_handler_removed_.is_null())
          on_protocol_handler_removed_.Run(object_path);
        protocol_handler_instances_.erase(p);
      }
      return;
    }
    if (interface_name == "org.chromium.WebServer.Server") {
      auto p = server_instances_.find(object_path);
      if (p != server_instances_.end()) {
        if (!on_server_removed_.is_null())
          on_server_removed_.Run(object_path);
        server_instances_.erase(p);
      }
      return;
    }
  }

  dbus::PropertySet* CreateProperties(
      dbus::ObjectProxy* object_proxy,
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.WebServer.ProtocolHandler") {
      return new org::chromium::WebServer::ProtocolHandlerProxy::PropertySet{
          object_proxy,
          base::Bind(&ObjectManagerProxy::OnPropertyChanged,
                     weak_ptr_factory_.GetWeakPtr(),
                     object_path,
                     interface_name)
      };
    }
    if (interface_name == "org.chromium.WebServer.Server") {
      return new org::chromium::WebServer::ServerProxy::PropertySet{
          object_proxy,
          base::Bind(&ObjectManagerProxy::OnPropertyChanged,
                     weak_ptr_factory_.GetWeakPtr(),
                     object_path,
                     interface_name)
      };
    }
    LOG(FATAL) << "Creating properties for unsupported interface "
               << interface_name;
    return nullptr;
  }

  scoped_refptr<dbus::Bus> bus_;
  dbus::ObjectManager* dbus_object_manager_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::WebServer::ProtocolHandlerProxy>> protocol_handler_instances_;
  base::Callback<void(org::chromium::WebServer::ProtocolHandlerProxyInterface*)> on_protocol_handler_added_;
  base::Callback<void(const dbus::ObjectPath&)> on_protocol_handler_removed_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::WebServer::ServerProxy>> server_instances_;
  base::Callback<void(org::chromium::WebServer::ServerProxyInterface*)> on_server_added_;
  base::Callback<void(const dbus::ObjectPath&)> on_server_removed_;
  base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(ObjectManagerProxy);
};

}  // namespace WebServer
}  // namespace chromium
}  // namespace org

同时会生成proxy端的动态链接库libwebserd-client-internal.so:

[ 53% 32/60] /bin/bash -c "(true) && (mkdir -p out/target/product/rpi/obj/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/LINKED/) && (prebuilts/clang/host/linux-x86/3.8/bin/clang++ -nostdlib -Wl,-soname,libwebservd-client-internal.so -Wl,--gc-sections -shared  -Lout/target/product/rpi/obj/lib out/target/product/rpi/obj/lib/crtbegin_so.o                      -Wl,--whole-archive   -Wl,--no-whole-archive   out/target/product/rpi/obj/STATIC_LIBRARIES/libunwind_llvm_intermediates/libunwind_llvm.a out/target/product/rpi/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a   prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/lib/armv7-a/libatomic.a prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9/armv7-a/libgcc.a -lc++ -ldl -lc -lm  -o out/target/product/rpi/obj/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/LINKED/libwebservd-client-internal.so   -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--build-id=md5 -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--icf=safe -Wl,--hash-style=gnu -Wl,--no-undefined-version -Wl,--fix-cortex-a8    -target arm-linux-androideabi -Bprebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/arm-linux-androideabi/bin   -Wl,--exclude-libs,libunwind_llvm.a -Wl,--no-undefined out/target/product/rpi/obj/lib/crtend_so.o)"

可见,libwebservd-client-internal.so并不包含webservd相关的代码,它只是作了一个依赖文件而存在。

  • 相关的makefile

build/core/binary.mk:

###########################################################
## Compile the .dbus-xml files to c++ headers
###########################################################
dbus_definitions := $(filter %.dbus-xml,$(my_src_files))
dbus_generated_headers :=
ifneq ($(dbus_definitions),)

dbus_definition_paths := $(addprefix $(LOCAL_PATH)/,$(dbus_definitions))
dbus_service_config := $(filter %dbus-service-config.json,$(my_src_files))
dbus_service_config_path := $(addprefix $(LOCAL_PATH)/,$(dbus_service_config))

dbus_gen_dir := $(generated_sources_dir)/dbus_bindings

ifdef LOCAL_DBUS_PROXY_PREFIX
dbus_header_dir := $(dbus_gen_dir)/include/$(LOCAL_DBUS_PROXY_PREFIX)
dbus_headers := dbus-proxies.h
else
dbus_header_dir := $(dbus_gen_dir)
dbus_headers := $(patsubst %.dbus-xml,%.h,$(dbus_definitions))
endif
dbus_generated_headers := $(addprefix $(dbus_header_dir)/,$(dbus_headers))

# Ensure that we only define build rules once in multilib builds.
ifndef $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined
$(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined := true

$(dbus_generated_headers): PRIVATE_MODULE := $(LOCAL_MODULE)
$(dbus_generated_headers): PRIVATE_DBUS_SERVICE_CONFIG := $(dbus_service_config_path)
$(dbus_generated_headers) : $(dbus_service_config_path) $(DBUS_GENERATOR)
ifdef LOCAL_DBUS_PROXY_PREFIX
$(dbus_generated_headers) : $(dbus_definition_paths)
	$(generate-dbus-proxies)
else
$(dbus_generated_headers) : $(dbus_header_dir)/%.h : $(LOCAL_PATH)/%.dbus-xml
	$(generate-dbus-adaptors)
endif  # $(LOCAL_DBUS_PROXY_PREFIX)
endif  # $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined

ifdef LOCAL_DBUS_PROXY_PREFIX
# Auto-export the generated dbus proxy directory.
my_export_c_include_dirs += $(dbus_gen_dir)/include
my_c_includes += $(dbus_gen_dir)/include
else
my_export_c_include_dirs += $(dbus_header_dir)
my_c_includes += $(dbus_header_dir)
endif  # $(LOCAL_DBUS_PROXY_PREFIX)

my_generated_sources += $(dbus_generated_headers)

endif  # $(dbus_definitions) non-empty

build/core/definition.mk – generate DBus adapter

######################################################################
## Commands for generating DBus adaptors from .dbus-xml files.
######################################################################
define generate-dbus-adaptors
@echo "Generating DBus adaptors for $(PRIVATE_MODULE)"
@mkdir -p $(dir $@)
$(hide) $(DBUS_GENERATOR) \
	--service-config=$(PRIVATE_DBUS_SERVICE_CONFIG) \
	--adaptor=$@ \
	$<
endef

build/core/definition.mk – generate DBus proxies

######################################################################
## Commands for generating DBus proxies from .dbus-xml files.
######################################################################
define generate-dbus-proxies
@echo "Generating DBus proxies for $(PRIVATE_MODULE)"
@mkdir -p $(dir $@)
$(hide) $(DBUS_GENERATOR) \
	--service-config=$(PRIVATE_DBUS_SERVICE_CONFIG) \
	--proxy=$@ \
	$(filter %.dbus-xml,$^)
endef

这东西真不好写,简单地说dbus相关的文件都会被dbus-binding-generator转换成cpp的头文件,并且会生成server(adapter)和client(proxy)两种类型的头文件。

从system/weaved提交的代码来看(brillo-m8-dev -> brillo-m9-dev), D-Bus有被Binder取代的趋势:

commit ae29f7d91a0b4178556eeb6b99fd05d90fcefd3d
Author: Alex Vakulenko <avakulenko@google.com>
Date:   Mon Dec 21 16:30:37 2015 -0800

    Add Binder support to weaved and remove D-Bus interface
    
    Added binder-based IPC to weaved instead of D-Bus. Removed the
    old weave commands based on D-Bus and redesigned client library
    interface to be more in line with how Binder operates.
    
    BUG: 23782171, 25523591
    
    Change-Id: Ic39a6a2edf2e033e506d233919c9d04e4fab8d01

相关的参考文档:

  1. https://dbus.freedesktop.org/doc/dbus-tutorial.html
  2. external/dbus
  3. external/dbus-binding-generator

评论

2 Comments on "Brillo开发: system/webservd代码分析 – webservd – D-Bus service"

提醒我
avatar

Linfu
游客
Linfu
2 年 7 月 之前

请教下libweave、weaved、webservd 这三者的关系是怎样的呢?
想学习weave协议的话怎样入手好点呢?谢谢!

wpDiscuz