Invoke HIDL for C++ files

Change-Id: I917a04e92484f968b05b269bbaa2d458a7729b4c
(cherry picked from commit bbccdd6d152a37a03ece027b5896ddbc42db8a8b)
diff --git a/core/binary.mk b/core/binary.mk
index 90a2156..e221cab 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -862,6 +862,39 @@
 endif  # $(vts_src) non-empty
 
 ###########################################################
+## Compile the .hidl files to .cpp and then to .o
+###########################################################
+
+hidl_src := $(strip $(filter %.hidl,$(my_src_files)))
+hidl_gen_cpp :=
+ifneq ($(hidl_src),)
+
+# Use the intermediates directory to avoid writing our own .cpp -> .o rules.
+hidl_gen_cpp_root := $(intermediates)/hidl-generated/src
+hidl_gen_include_root := $(intermediates)/hidl-generated/include
+
+# Multi-architecture builds have distinct intermediates directories.
+# Thus we'll actually generate source for each architecture.
+$(foreach s,$(hidl_src),\
+    $(eval $(call define-hidl-cpp-rule,$(s),$(hidl_gen_cpp_root),hidl_gen_cpp)))
+$(foreach cpp,$(hidl_gen_cpp), \
+    $(call include-depfile,$(addsuffix .hidl.P,$(basename $(cpp))),$(cpp)))
+$(call track-src-file-gen,$(hidl_src),$(hidl_gen_cpp))
+
+$(hidl_gen_cpp) : PRIVATE_MODULE := $(LOCAL_MODULE)
+$(hidl_gen_cpp) : PRIVATE_HEADER_OUTPUT_DIR := $(hidl_gen_include_root)
+$(hidl_gen_cpp) : PRIVATE_SRC_OUTPUT_DIR := $(hidl_gen_cpp_root)
+$(hidl_gen_cpp) : PRIVATE_HIDL_FLAGS := $(addprefix -I,$(LOCAL_HIDL_INCLUDES))
+
+# Add generated headers to include paths.
+my_c_includes += $(hidl_gen_include_root)
+my_export_c_include_dirs += $(hidl_gen_include_root)
+# Pick up the generated C++ files later for transformation to .o files.
+my_generated_sources += $(hidl_gen_cpp)
+
+endif  # $(hidl_src) non-empty
+
+###########################################################
 ## YACC: Compile .y/.yy files to .c/.cpp and then to .o.
 ###########################################################
 
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index e271dd2..ff44320 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -107,6 +107,7 @@
 LOCAL_MANIFEST_INSTRUMENTATION_FOR:=
 LOCAL_AIDL_INCLUDES:=
 LOCAL_VTS_INCLUDES:=
+LOCAL_HIDL_INCLUDES:=
 LOCAL_JARJAR_RULES:=
 LOCAL_ADDITIONAL_JAVA_DIR:=
 LOCAL_ALLOW_UNDEFINED_SYMBOLS:=
@@ -144,6 +145,7 @@
 LOCAL_PROTOC_FLAGS:=
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
 LOCAL_VTSC_FLAGS:=
+LOCAL_HIDL_FLAGS:=
 LOCAL_NO_CRT:=
 LOCAL_NO_LIBGCC:=
 LOCAL_PROPRIETARY_MODULE:=
diff --git a/core/config.mk b/core/config.mk
index 0250516..4cd4f42 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -541,6 +541,7 @@
                external/nanopb-c/generator/google/*.py \
                external/nanopb-c/generator/proto/*.py)
 VTSC := $(HOST_OUT_EXECUTABLES)/vtsc$(HOST_EXECUTABLE_SUFFIX)
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
 DBUS_GENERATOR := $(HOST_OUT_EXECUTABLES)/dbus-binding-generator
 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 1ef73e9..291e638 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -316,6 +316,24 @@
 endef
 
 ###########################################################
+## Find all files named "*.hidl" under the named directories,
+## which must be relative to $(LOCAL_PATH).  The returned list
+## is relative to $(LOCAL_PATH).
+###########################################################
+
+define all-hidl-files-under
+$(call all-named-files-under,*.hidl,$(1))
+endef
+
+###########################################################
+## Find all of the "*.hidl" files under $(LOCAL_PATH).
+###########################################################
+
+define all-subdir-hidl-files
+$(call all-hidl-files-under,.)
+endef
+
+###########################################################
 ## Find all of the logtags files under the named directories.
 ## Meant to be used like:
 ##    SRC_FILES := $(call all-logtags-files-under,src)
@@ -1123,6 +1141,33 @@
 endef
 
 ###########################################################
+## Commands for running hidl-gen
+###########################################################
+
+define transform-hidl-to-cpp
+@mkdir -p $(dir $@)
+@mkdir -p $(PRIVATE_HEADER_OUTPUT_DIR)
+@mkdir -p $(PRIVATE_SRC_OUTPUT_DIR)
+@echo "Generating C++ from HIDL: $(PRIVATE_MODULE) <= $<"
+$(hide) $(HIDL) -d$(basename $@).hidl.P $(PRIVATE_HIDL_FLAGS) \
+    all_cpps $< $(PRIVATE_HEADER_OUTPUT_DIR) $@
+endef
+
+## Given a .hidl file path generate the rule to compile it to .cpp and .h files.
+# $(1): a .hidl source file
+# $(2): a directory to place the generated .cpp and .h files in
+# $(3): name of a variable to add the path to the generated source files to
+#
+# You must call this with $(eval).
+define define-hidl-cpp-rule
+my_tracked_source_files += $@
+define-hidl-cpp-rule-src := $(patsubst %.hidl,%$(LOCAL_CPP_EXTENSION),$(subst ../,dotdot/,$(addprefix $(2)/,$(1))))
+$$(define-hidl-cpp-rule-src) : $(LOCAL_PATH)/$(1) $(HIDL)
+	$$(transform-hidl-to-cpp)
+$(3) += $$(define-hidl-cpp-rule-src)
+endef
+
+###########################################################
 ## Commands for running java-event-log-tags.py
 ###########################################################