Add build rules to generate native DBus interfaces

With this patch, we can now write Android makefiles like:

include $(CLEAR_VARS)
LOCAL_MODULE := dbus-binding-example
LOCAL_SRC_FILES := main.cpp \
                   dbus-service-config.json \
                   org.example.Daemon.Command.dbus.xml \
                   org.example.Daemon.Manager.dbus.xml
include $(BUILD_EXECUTABLE)

This will cause header files defining native DBus interfaces
to be generated.  These can be included from main.cpp to
easily expose object oriented interface over DBus.

Bug: 22608897
Change-Id: Ic4304ac8de77de74d6955ed17789e5477be9a53e
diff --git a/core/binary.mk b/core/binary.mk
index e18f8c8..f300b2f 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -570,6 +570,51 @@
 
 
 ###########################################################
+## Compile the .dbus.xml files to c++ headers
+###########################################################
+dbus_if_sources := $(filter %.dbus.xml,$(my_src_files))
+ifneq ($(dbus_if_sources),)
+
+dbus_if_sources_full_path := $(addprefix $(LOCAL_PATH)/,$(dbus_if_sources))
+dbus_service_config := $(filter %dbus-service-config.json,$(my_src_files))
+dbus_service_config_full_path := $(addprefix $(LOCAL_PATH)/,$(dbus_service_config))
+
+dbus_header_prefix := $(generated_sources_dir)/dbus-bindings/$(LOCAL_MODULE)
+dbus_adaptors_header := $(dbus_header_prefix)/adaptors.h
+dbus_proxies_header := $(dbus_header_prefix)/proxies.h
+dbus_method_names_header := $(dbus_header_prefix)/method_names.h
+
+dbus_generated_source_dependencies := \
+    $(dbus_if_sources_full_path) \
+    $(dbus_service_config_full_path) \
+    $(DBUS_GENERATOR)
+
+# 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_adaptors_header) : PRIVATE_DBUS_MODULE := $(LOCAL_MODULE)
+$(dbus_adaptors_header) : PRIVATE_DBUS_HEADER_DIRECTORY := $(dbus_header_prefix)
+$(dbus_adaptors_header) : PRIVATE_DBUS_SERVICE_CONFIG := $(dbus_service_config_full_path)
+$(dbus_adaptors_header) : PRIVATE_DBUS_ADAPTORS_HEADER := $(dbus_adaptors_header)
+$(dbus_adaptors_header) : PRIVATE_DBUS_PROXIES_HEADER := $(dbus_proxies_header)
+$(dbus_adaptors_header) : PRIVATE_DBUS_METHOD_NAMES_HEADER := $(dbus_method_names_header)
+$(dbus_adaptors_header) : PRIVATE_DBUS_INTERFACE_DEFINITIONS := $(dbus_if_sources_full_path)
+$(dbus_adaptors_header) : $(dbus_generated_source_dependencies)
+	$(generate-dbus-bindings)
+# These are actually generated by the above recipe, but we'd like to make the
+# dependency chain complete.
+$(dbus_proxies_header) : $(dbus_adaptors_header)
+$(dbus_method_names_header) : $(dbus_adaptors_header)
+endif  # $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined
+
+my_generated_sources += \
+    $(dbus_adaptors_header) \
+    $(dbus_proxies_header) \
+    $(dbus_method_names_header)
+endif  # $(dbus_if_sources) non-empty
+
+
+###########################################################
 ## YACC: Compile .y and .yy files to .cpp and the to .o.
 ###########################################################
 
diff --git a/core/config.mk b/core/config.mk
index 882ab0c..fec018b 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -399,6 +399,7 @@
 AAPT := $(HOST_OUT_EXECUTABLES)/aapt$(HOST_EXECUTABLE_SUFFIX)
 AIDL := $(HOST_OUT_EXECUTABLES)/aidl$(HOST_EXECUTABLE_SUFFIX)
 PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
+DBUS_GENERATOR := $(HOST_OUT_EXECUTABLES)/dbus-binding-generator
 SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
 MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/definitions.mk b/core/definitions.mk
index f688f41..7760306 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -968,6 +968,21 @@
 endef
 
 
+######################################################################
+## Commands for running protoc to compile .proto into .pb.cc and .pb.h
+######################################################################
+define generate-dbus-bindings
+@echo "Generating DBus bindings for $(PRIVATE_DBUS_MODULE)"
+@mkdir -p $(PRIVATE_DBUS_HEADER_DIRECTORY)
+$(hide) $(DBUS_GENERATOR) \
+	--service-config=$(PRIVATE_DBUS_SERVICE_CONFIG) \
+	--adaptor=$(PRIVATE_DBUS_ADAPTORS_HEADER) \
+	--proxy=$(PRIVATE_DBUS_PROXIES_HEADER) \
+	--method-names=$(PRIVATE_DBUS_METHOD_NAMES_HEADER) \
+	$(PRIVATE_DBUS_INTERFACE_DEFINITIONS)
+endef
+
+
 ###########################################################
 ## Commands for running gcc to compile a C++ file
 ###########################################################