Merge "DO NOT MERGE Always statically include Support Libraries, move SDK definitions up a dir" into pi-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index fd12a78..b58c2e6 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -467,6 +467,19 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/DisplayCutoutEmulationWide)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/DisplayCutoutEmulationNarrow)
 
+# Remove obsolete intermedates src files
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/*/*_intermediates/src/RenderScript.stamp*)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/java-source-list)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*_intermediates/java-source-list)
+$(call add-clean-step, rm -rf $(OUT_DOCS)/*-timestamp)
+
+$(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/APPS/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/JAVA_LIBRARIES/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/APPS/*_intermediates/java-source-list)
+$(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/JAVA_LIBRARIES/*_intermediates/java-source-list)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/aapt2.mk b/core/aapt2.mk
index 7d9d8ce..109bb39 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -78,12 +78,17 @@
 $(my_res_package): PRIVATE_AAPT_FLAGS += $(addprefix --split ,$(join $(built_apk_splits),$(addprefix :,$(my_apk_split_configs))))
 endif
 
+my_srcjar := $(intermediates.COMMON)/aapt2.srcjar
+LOCAL_SRCJARS += $(my_srcjar)
+
 $(my_res_package): PRIVATE_RES_FLAT := $(my_res_resources_flat)
 $(my_res_package): PRIVATE_OVERLAY_FLAT := $(my_static_library_resources) $(my_resources_flata) $(my_overlay_resources_flat)
 $(my_res_package): PRIVATE_SHARED_ANDROID_LIBRARIES := $(my_shared_library_resources)
 $(my_res_package): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
 $(my_res_package): PRIVATE_ASSET_DIRS := $(my_asset_dirs)
-$(my_res_package): .KATI_IMPLICIT_OUTPUTS :=
+$(my_res_package): PRIVATE_JAVA_GEN_DIR := $(intermediates.COMMON)/aapt2
+$(my_res_package): PRIVATE_SRCJAR := $(my_srcjar)
+$(my_res_package): .KATI_IMPLICIT_OUTPUTS := $(my_srcjar)
 
 ifdef R_file_stamp
 $(my_res_package): PRIVATE_R_FILE_STAMP := $(R_file_stamp)
@@ -108,12 +113,12 @@
 $(my_res_package): $(my_full_asset_paths)
 $(my_res_package): $(my_res_resources_flat) $(my_overlay_resources_flat) \
   $(my_resources_flata) $(my_static_library_resources) \
-  $(AAPT2)
+  $(AAPT2) $(SOONG_ZIP)
 	@echo "AAPT2 link $@"
 	$(call aapt2-link)
 ifdef R_file_stamp
 	@rm -f $(PRIVATE_R_FILE_STAMP)
-	$(call find-generated-R.java,$(PRIVATE_R_FILE_STAMP))
+	$(call find-generated-R.java,$(PRIVATE_JAVA_GEN_DIR),$(PRIVATE_R_FILE_STAMP))
 endif
 ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
 	@rm -f $(PRIVATE_RESOURCE_EXPORT_PACKAGE)
diff --git a/core/aapt_flags.mk b/core/aapt_flags.mk
index 4e3493a..13d4817 100644
--- a/core/aapt_flags.mk
+++ b/core/aapt_flags.mk
@@ -13,8 +13,3 @@
     aapt_flags :=
   endif
 endif
-
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 9415143..35d077c 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -217,19 +217,17 @@
 
       # Respect LOCAL_NOSANITIZE for integer-overflow flags.
       ifeq ($(filter signed-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
-        my_cflags += -fsanitize=signed-integer-overflow
+        my_sanitize += signed-integer-overflow
       endif
       ifeq ($(filter unsigned-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
-        my_cflags += -fsanitize=unsigned-integer-overflow
+        my_sanitize += unsigned-integer-overflow
       endif
-      my_cflags += -fsanitize-trap=all
-      my_cflags += -ftrap-function=abort
       my_cflags += $(INTEGER_OVERFLOW_EXTRA_CFLAGS)
 
       # Check for diagnostics mode (on by default).
       ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
-        my_cflags += -fno-sanitize-trap=signed-integer-overflow,unsigned-integer-overflow
-        my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY) $(my_shared_libraries)
+        my_sanitize_diag += signed-integer-overflow
+        my_sanitize_diag += unsigned-integer-overflow
       endif
     endif
   endif
@@ -326,6 +324,27 @@
   endif
 endif
 
+# Use minimal diagnostics when integer overflow is enabled
+ifndef LOCAL_IS_HOST_MODULE
+  # Pre-emptively add UBSAN minimal runtime incase a static library dependency requires it
+  ifeq ($(filter STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+    ifndef LOCAL_SDK_VERSION
+      my_static_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY)
+    endif
+  endif
+  ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
+    ifeq ($(filter unsigned-integer-overflow signed-integer overflow integer,$(my_sanitize_diag)),)
+      ifeq ($(filter cfi,$(my_sanitize_diag)),)
+        ifeq ($(filter address,$(my_sanitize)),)
+          my_cflags += -fsanitize-minimal-runtime
+          my_cflags += -fno-sanitize-trap=integer
+          my_cflags += -fno-sanitize-recover=integer
+        endif
+      endif
+    endif
+  endif
+endif
+
 ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),)
   recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
   my_cflags += -fsanitize-recover=$(recover_arg)
diff --git a/core/definitions.mk b/core/definitions.mk
index e6bd194..a872550 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1036,9 +1036,9 @@
   $(PRIVATE_RS_FLAGS) \
   $(foreach inc,$(PRIVATE_RS_INCLUDES),$(addprefix -I , $(inc))) \
   $(PRIVATE_RS_SOURCE_FILES)
+$(SOONG_ZIP) -o $@ -C $(PRIVATE_RS_OUTPUT_DIR)/src -D $(PRIVATE_RS_OUTPUT_DIR)/src
+$(SOONG_ZIP) -o $(PRIVATE_RS_OUTPUT_RES_ZIP) -C $(PRIVATE_RS_OUTPUT_DIR)/res -D $(PRIVATE_RS_OUTPUT_DIR)/res
 $(call _merge-renderscript-d,$(PRIVATE_DEP_FILES),$@.d)
-$(hide) mkdir -p $(dir $@)
-$(hide) touch $@
 endef
 
 define transform-bc-to-so
@@ -2021,11 +2021,12 @@
 # This rule creates the R.java and Manifest.java files, both of which
 # are PRODUCT-neutral.  Don't pass PRIVATE_PRODUCT_AAPT_CONFIG to this invocation.
 define create-resource-java-files
-@mkdir -p $(PRIVATE_SOURCE_INTERMEDIATES_DIR)
 @mkdir -p $(dir $(PRIVATE_RESOURCE_PUBLICS_OUTPUT))
+rm -rf $(PRIVATE_JAVA_GEN_DIR)
+mkdir -p $(PRIVATE_JAVA_GEN_DIR)
 $(hide) $(AAPT_ASAN_OPTIONS) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m \
     $(eval # PRIVATE_PRODUCT_AAPT_CONFIG is intentionally missing-- see comment.) \
-    $(addprefix -J , $(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
+    $(addprefix -J , $(PRIVATE_JAVA_GEN_DIR)) \
     $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
     $(addprefix -P , $(PRIVATE_RESOURCE_PUBLICS_OUTPUT)) \
     $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
@@ -2039,30 +2040,31 @@
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
     $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
     --skip-symbols-without-default-localization
+$(SOONG_ZIP) -o $(PRIVATE_SRCJAR) -C $(PRIVATE_JAVA_GEN_DIR) -D $(PRIVATE_JAVA_GEN_DIR)
 # So that we re-run aapt when the list of input files change
 $(hide) echo $(PRIVATE_RESOURCE_LIST) >/dev/null
 endef
 
-# Search for generated R.java/Manifest.java, copy the found R.java as $1.
+# Search for generated R.java/Manifest.java in $1, copy the found R.java as $2.
 # Also copy them to a central 'R' directory to make it easier to add the files to an IDE.
 define find-generated-R.java
-$(hide) for GENERATED_MANIFEST_FILE in `find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) \
+$(hide) for GENERATED_MANIFEST_FILE in `find $(1) \
   -name Manifest.java 2> /dev/null`; do \
     dir=`awk '/package/{gsub(/\./,"/",$$2);gsub(/;/,"",$$2);print $$2;exit}' $$GENERATED_MANIFEST_FILE`; \
     mkdir -p $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
     $(ACP) -fp $$GENERATED_MANIFEST_FILE $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
   done;
-$(hide) for GENERATED_R_FILE in `find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) \
+$(hide) for GENERATED_R_FILE in `find $(1) \
   -name R.java 2> /dev/null`; do \
     dir=`awk '/package/{gsub(/\./,"/",$$2);gsub(/;/,"",$$2);print $$2;exit}' $$GENERATED_R_FILE`; \
     mkdir -p $(TARGET_COMMON_OUT_ROOT)/R/$$dir; \
     $(ACP) -fp $$GENERATED_R_FILE $(TARGET_COMMON_OUT_ROOT)/R/$$dir \
       || exit 31; \
-    $(ACP) -fp $$GENERATED_R_FILE $1 || exit 32; \
+    $(ACP) -fp $$GENERATED_R_FILE $(2) || exit 32; \
   done;
 @# Ensure that the target file is always created, i.e. also in case we did not
 @# enter the GENERATED_R_FILE-loop above. This avoids unnecessary rebuilding.
-$(hide) touch $1
+$(hide) touch $(2)
 endef
 
 ###########################################################
@@ -2110,6 +2112,8 @@
 
 define aapt2-link
 @mkdir -p $(dir $@)
+rm -rf $(PRIVATE_JAVA_GEN_DIR)
+mkdir -p $(PRIVATE_JAVA_GEN_DIR)
 $(call dump-words-to-file,$(PRIVATE_RES_FLAT),$(dir $@)aapt2-flat-list)
 $(call dump-words-to-file,$(PRIVATE_OVERLAY_FLAT),$(dir $@)aapt2-flat-overlay-list)
 $(hide) $(AAPT2) link -o $@ \
@@ -2118,7 +2122,7 @@
   $(addprefix -I ,$(PRIVATE_AAPT_INCLUDES)) \
   $(addprefix -I ,$(PRIVATE_SHARED_ANDROID_LIBRARIES)) \
   $(addprefix -A ,$(PRIVATE_ASSET_DIR)) \
-  $(addprefix --java ,$(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
+  $(addprefix --java ,$(PRIVATE_JAVA_GEN_DIR)) \
   $(addprefix --proguard ,$(PRIVATE_PROGUARD_OPTIONS_FILE)) \
   $(addprefix --min-sdk-version ,$(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
   $(addprefix --target-sdk-version ,$(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
@@ -2131,6 +2135,7 @@
   $(addprefix --rename-instrumentation-target-package ,$(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
   -R \@$(dir $@)aapt2-flat-overlay-list \
   \@$(dir $@)aapt2-flat-list
+$(SOONG_ZIP) -o $(PRIVATE_SRCJAR) -C $(PRIVATE_JAVA_GEN_DIR) -D $(PRIVATE_JAVA_GEN_DIR)
 endef
 
 ###########################################################
@@ -2212,8 +2217,6 @@
 fi
 $(if $(PRIVATE_HAS_PROTO_SOURCES), \
     $(hide) find $(PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR) -name '*.java' -and -not -name '.*' >> $(1))
-$(if $(PRIVATE_HAS_RS_SOURCES), \
-    $(hide) find $(PRIVATE_RS_SOURCE_INTERMEDIATES_DIR) -name '*.java' -and -not -name '.*' >> $(1))
 endef
 
 # Some historical notes:
@@ -2296,9 +2299,9 @@
     $(addprefix --classpath ,$(strip \
         $(call normalize-path-list,$(PRIVATE_ALL_JAVA_HEADER_LIBRARIES)))) \
     || ( rm -rf $(dir $@)/classes-turbine ; exit 41 ) && \
-    $(MERGE_ZIPS) -j -stripDir META-INF $@.tmp $@.premerged $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
+    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $@.premerged $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
 else \
-    $(MERGE_ZIPS) -j -stripDir META-INF $@.tmp $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
+    $(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
 fi
 $(hide) $(ZIPTIME) $@.tmp
 $(hide) $(call commit-change-for-toc,$@)
diff --git a/core/java.mk b/core/java.mk
index 019a989..3eb9086 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -102,159 +102,6 @@
 
 LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
 
-###############################################################
-## .rs files: RenderScript sources to .java files and .bc files
-###############################################################
-renderscript_sources := $(filter %.rs,$(LOCAL_SRC_FILES))
-# Because names of the java files from RenderScript are unknown until the
-# .rs file(s) are compiled, we have to depend on a timestamp file.
-RenderScript_file_stamp :=
-rs_generated_res_dir :=
-rs_compatibility_jni_libs :=
-ifneq ($(renderscript_sources),)
-renderscript_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(renderscript_sources))
-RenderScript_file_stamp := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/RenderScript.stamp
-renderscript_intermediate.COMMON := $(intermediates.COMMON)/renderscript
-
-# Defaulting to an empty string uses the latest available platform SDK.
-renderscript_target_api :=
-
-ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
-  renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
-else
-  ifneq (,$(LOCAL_SDK_VERSION))
-    # Set target-api for LOCAL_SDK_VERSIONs other than current.
-    ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
-      renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
-    endif
-  endif  # LOCAL_SDK_VERSION is set
-endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
-
-# For 64-bit, we always have to upgrade to at least 21 for compat build.
-ifneq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),)
-  ifeq ($(TARGET_IS_64_BIT),true)
-    ifneq ($(filter $(RSCOMPAT_32BIT_ONLY_API_LEVELS),$(renderscript_target_api)),)
-      renderscript_target_api := 21
-    endif
-  endif
-endif
-
-ifeq ($(LOCAL_RENDERSCRIPT_CC),)
-LOCAL_RENDERSCRIPT_CC := $(LLVM_RS_CC)
-endif
-
-# Turn on all warnings and warnings as errors for RS compiles.
-# This can be disabled with LOCAL_RENDERSCRIPT_FLAGS := -Wno-error
-renderscript_flags := -Wall -Werror
-renderscript_flags += $(LOCAL_RENDERSCRIPT_FLAGS)
-
-# prepend the RenderScript system include path
-ifneq ($(filter-out current system_current test_current core_current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_VERSION))),)
-# if a numeric LOCAL_SDK_VERSION, or current LOCAL_SDK_VERSION with TARGET_BUILD_APPS
-LOCAL_RENDERSCRIPT_INCLUDES := \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/clang-include \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/include \
-    $(LOCAL_RENDERSCRIPT_INCLUDES)
-else
-LOCAL_RENDERSCRIPT_INCLUDES := \
-    $(TOPDIR)external/clang/lib/Headers \
-    $(TOPDIR)frameworks/rs/script_api/include \
-    $(LOCAL_RENDERSCRIPT_INCLUDES)
-endif
-
-ifneq ($(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE),)
-LOCAL_RENDERSCRIPT_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE)
-endif
-
-bc_files := $(patsubst %.rs,%.bc, $(notdir $(renderscript_sources)))
-bc_dep_files := $(addprefix $(renderscript_intermediate.COMMON)/,$(patsubst %.bc,%.d,$(bc_files)))
-
-$(RenderScript_file_stamp): PRIVATE_RS_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES)
-$(RenderScript_file_stamp): PRIVATE_RS_CC := $(LOCAL_RENDERSCRIPT_CC)
-$(RenderScript_file_stamp): PRIVATE_RS_FLAGS := $(renderscript_flags)
-$(RenderScript_file_stamp): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
-# By putting the generated java files into $(LOCAL_INTERMEDIATE_SOURCE_DIR), they will be
-# automatically found by the java compiling function transform-java-to-classes.jar.
-$(RenderScript_file_stamp): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate.COMMON)
-$(RenderScript_file_stamp): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
-$(RenderScript_file_stamp): PRIVATE_DEP_FILES := $(bc_dep_files)
-$(RenderScript_file_stamp): $(renderscript_sources_fullpath) $(LOCAL_RENDERSCRIPT_CC)
-	$(transform-renderscripts-to-java-and-bc)
-
-# include the dependency files (.d/.P) generated by llvm-rs-cc.
-$(call include-depfile,$(RenderScript_file_stamp).P,$(RenderScript_file_stamp))
-
-ifneq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),)
-
-
-ifeq ($(filter $(RSCOMPAT_32BIT_ONLY_API_LEVELS),$(renderscript_target_api)),)
-ifeq ($(TARGET_IS_64_BIT),true)
-renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc64/
-else
-renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc32/
-endif
-else
-renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/
-endif
-
-rs_generated_bc := $(addprefix \
-    $(renderscript_intermediate.bc_folder), $(bc_files))
-
-renderscript_intermediate := $(intermediates)/renderscript
-
-# We don't need the .so files in bundled branches
-# Prevent these from showing up on the device
-# One exception is librsjni.so, which is needed for
-# both native path and compat path.
-rs_jni_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/librsjni.so
-LOCAL_JNI_SHARED_LIBRARIES += librsjni
-
-ifneq (,$(TARGET_BUILD_APPS)$(FORCE_BUILD_RS_COMPAT))
-
-rs_compatibility_jni_libs := $(addprefix \
-    $(renderscript_intermediate)/librs., \
-    $(patsubst %.bc,%.so, $(bc_files)))
-
-$(rs_generated_bc) : $(RenderScript_file_stamp)
-
-rs_support_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupport.so
-LOCAL_JNI_SHARED_LIBRARIES += libRSSupport
-
-rs_support_io_lib :=
-# check if the target api level support USAGE_IO
-ifeq ($(filter $(RSCOMPAT_NO_USAGEIO_API_LEVELS),$(renderscript_target_api)),)
-rs_support_io_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupportIO.so
-LOCAL_JNI_SHARED_LIBRARIES += libRSSupportIO
-endif
-
-my_arch := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
-ifneq (,$(filter arm64 mips64 x86_64,$(my_arch)))
-  my_min_sdk_version := 21
-else
-  my_min_sdk_version := $(MIN_SUPPORTED_SDK_VERSION)
-endif
-
-$(rs_compatibility_jni_libs): $(RenderScript_file_stamp) $(RS_PREBUILT_CLCORE) \
-    $(rs_support_lib) $(rs_support_io_lib) $(rs_jni_lib) $(rs_compiler_rt)
-$(rs_compatibility_jni_libs): $(BCC_COMPAT)
-$(rs_compatibility_jni_libs): PRIVATE_CXX := $(CXX_WRAPPER) $(TARGET_CXX)
-$(rs_compatibility_jni_libs): PRIVATE_SDK_VERSION := $(my_min_sdk_version)
-$(rs_compatibility_jni_libs): $(renderscript_intermediate)/librs.%.so: \
-    $(renderscript_intermediate.bc_folder)%.bc \
-    $(SOONG_OUT_DIR)/ndk.timestamp
-	$(transform-bc-to-so)
-
-endif
-
-endif
-
-LOCAL_INTERMEDIATE_TARGETS += $(RenderScript_file_stamp)
-# Make sure the generated resource will be added to the apk.
-rs_generated_res_dir := $(renderscript_intermediate.COMMON)/res
-LOCAL_RESOURCE_DIR := $(rs_generated_res_dir) $(LOCAL_RESOURCE_DIR)
-endif
-
-
 ###########################################################
 ## AIDL: Compile .aidl files to .java
 ###########################################################
@@ -330,9 +177,6 @@
 
 include $(BUILD_SYSTEM)/sdk_check.mk
 
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HAS_RS_SOURCES := $(if $(renderscript_sources),true)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RS_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/renderscript
-
 # Set the profile source so that the odex / profile code included from java.mk
 # can find it.
 #
@@ -399,7 +243,6 @@
 java_sources_deps := \
     $(java_sources) \
     $(java_resource_sources) \
-    $(RenderScript_file_stamp) \
     $(proto_java_sources_file_stamp) \
     $(LOCAL_SRCJARS) \
     $(LOCAL_ADDITIONAL_DEPENDENCIES)
diff --git a/core/java_common.mk b/core/java_common.mk
index 4b10d2d..2b85dc1 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -177,7 +177,7 @@
 #####################################
 ## Warn if there is unrecognized file in LOCAL_SRC_FILES.
 my_unknown_src_files := $(filter-out \
-  %.java %.aidl %.proto %.logtags %.rs, \
+  %.java %.aidl %.proto %.logtags, \
   $(LOCAL_SRC_FILES) $(LOCAL_INTERMEDIATE_SOURCES) $(LOCAL_GENERATED_SOURCES))
 ifneq ($(my_unknown_src_files),)
 $(warning $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Unused source files: $(my_unknown_src_files))
diff --git a/core/java_renderscript.mk b/core/java_renderscript.mk
new file mode 100644
index 0000000..191b3be
--- /dev/null
+++ b/core/java_renderscript.mk
@@ -0,0 +1,155 @@
+###############################################################
+## Renderscript support for java
+## Adds rules to convert .rs files to .java and .bc files
+###############################################################
+
+renderscript_sources := $(filter %.rs,$(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(filter-out %.rs,$(LOCAL_SRC_FILES))
+
+rs_generated_res_zip :=
+rs_generated_src_jar :=
+rs_compatibility_jni_libs :=
+ifneq ($(renderscript_sources),)
+renderscript_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(renderscript_sources))
+renderscript_intermediate.COMMON := $(intermediates.COMMON)/renderscript
+rs_generated_res_zip := $(renderscript_intermediate.COMMON)/res.zip
+rs_generated_src_jar := $(renderscript_intermediate.COMMON)/rs.srcjar
+
+LOCAL_SRCJARS += $(rs_generated_src_jar)
+
+# Defaulting to an empty string uses the latest available platform SDK.
+renderscript_target_api :=
+
+ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
+  renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
+else
+  ifneq (,$(LOCAL_SDK_VERSION))
+    # Set target-api for LOCAL_SDK_VERSIONs other than current.
+    ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
+      renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+    endif
+  endif  # LOCAL_SDK_VERSION is set
+endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
+
+# For 64-bit, we always have to upgrade to at least 21 for compat build.
+ifneq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),)
+  ifeq ($(TARGET_IS_64_BIT),true)
+    ifneq ($(filter $(RSCOMPAT_32BIT_ONLY_API_LEVELS),$(renderscript_target_api)),)
+      renderscript_target_api := 21
+    endif
+  endif
+endif
+
+ifeq ($(LOCAL_RENDERSCRIPT_CC),)
+LOCAL_RENDERSCRIPT_CC := $(LLVM_RS_CC)
+endif
+
+# Turn on all warnings and warnings as errors for RS compiles.
+# This can be disabled with LOCAL_RENDERSCRIPT_FLAGS := -Wno-error
+renderscript_flags := -Wall -Werror
+renderscript_flags += $(LOCAL_RENDERSCRIPT_FLAGS)
+
+# prepend the RenderScript system include path
+ifneq ($(filter-out current system_current test_current core_current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_VERSION))),)
+# if a numeric LOCAL_SDK_VERSION, or current LOCAL_SDK_VERSION with TARGET_BUILD_APPS
+LOCAL_RENDERSCRIPT_INCLUDES := \
+    $(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/clang-include \
+    $(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/include \
+    $(LOCAL_RENDERSCRIPT_INCLUDES)
+else
+LOCAL_RENDERSCRIPT_INCLUDES := \
+    $(TOPDIR)external/clang/lib/Headers \
+    $(TOPDIR)frameworks/rs/script_api/include \
+    $(LOCAL_RENDERSCRIPT_INCLUDES)
+endif
+
+ifneq ($(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE),)
+LOCAL_RENDERSCRIPT_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE)
+endif
+
+bc_files := $(patsubst %.rs,%.bc, $(notdir $(renderscript_sources)))
+bc_dep_files := $(addprefix $(renderscript_intermediate.COMMON)/,$(patsubst %.bc,%.d,$(bc_files)))
+
+$(rs_generated_src_jar): PRIVATE_RS_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES)
+$(rs_generated_src_jar): PRIVATE_RS_CC := $(LOCAL_RENDERSCRIPT_CC)
+$(rs_generated_src_jar): PRIVATE_RS_FLAGS := $(renderscript_flags)
+$(rs_generated_src_jar): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
+$(rs_generated_src_jar): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate.COMMON)
+$(rs_generated_src_jar): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
+$(rs_generated_src_jar): PRIVATE_DEP_FILES := $(bc_dep_files)
+$(rs_generated_src_jar): PRIVATE_RS_OUTPUT_RES_ZIP := $(rs_generated_res_zip)
+$(rs_generated_src_jar): .KATI_IMPLICIT_OUTPUTS := $(rs_generated_res_zip)
+$(rs_generated_src_jar): $(renderscript_sources_fullpath) $(LOCAL_RENDERSCRIPT_CC) $(SOONG_ZIP)
+	$(transform-renderscripts-to-java-and-bc)
+
+# include the dependency files (.d/.P) generated by llvm-rs-cc.
+$(call include-depfile,$(rs_generated_src_jar).P,$(rs_generated_src_jar))
+
+ifneq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),)
+
+
+ifeq ($(filter $(RSCOMPAT_32BIT_ONLY_API_LEVELS),$(renderscript_target_api)),)
+ifeq ($(TARGET_IS_64_BIT),true)
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc64/
+else
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc32/
+endif
+else
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/
+endif
+
+rs_generated_bc := $(addprefix \
+    $(renderscript_intermediate.bc_folder), $(bc_files))
+
+renderscript_intermediate := $(intermediates)/renderscript
+
+# We don't need the .so files in bundled branches
+# Prevent these from showing up on the device
+# One exception is librsjni.so, which is needed for
+# both native path and compat path.
+rs_jni_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/librsjni.so
+LOCAL_JNI_SHARED_LIBRARIES += librsjni
+
+ifneq (,$(TARGET_BUILD_APPS)$(FORCE_BUILD_RS_COMPAT))
+
+rs_compatibility_jni_libs := $(addprefix \
+    $(renderscript_intermediate)/librs., \
+    $(patsubst %.bc,%.so, $(bc_files)))
+
+$(rs_generated_src_jar): .KATI_IMPLICIT_OUTPUTS += $(rs_generated_bc)
+
+rs_support_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupport.so
+LOCAL_JNI_SHARED_LIBRARIES += libRSSupport
+
+rs_support_io_lib :=
+# check if the target api level support USAGE_IO
+ifeq ($(filter $(RSCOMPAT_NO_USAGEIO_API_LEVELS),$(renderscript_target_api)),)
+rs_support_io_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupportIO.so
+LOCAL_JNI_SHARED_LIBRARIES += libRSSupportIO
+endif
+
+my_arch := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+ifneq (,$(filter arm64 mips64 x86_64,$(my_arch)))
+  my_min_sdk_version := 21
+else
+  my_min_sdk_version := $(MIN_SUPPORTED_SDK_VERSION)
+endif
+
+$(rs_compatibility_jni_libs): $(RS_PREBUILT_CLCORE) \
+    $(rs_support_lib) $(rs_support_io_lib) $(rs_jni_lib) $(rs_compiler_rt)
+$(rs_compatibility_jni_libs): $(BCC_COMPAT)
+$(rs_compatibility_jni_libs): PRIVATE_CXX := $(CXX_WRAPPER) $(TARGET_CXX)
+$(rs_compatibility_jni_libs): PRIVATE_SDK_VERSION := $(my_min_sdk_version)
+$(rs_compatibility_jni_libs): $(renderscript_intermediate)/librs.%.so: \
+    $(renderscript_intermediate.bc_folder)%.bc \
+    $(SOONG_OUT_DIR)/ndk.timestamp
+	$(transform-bc-to-so)
+
+endif
+
+endif
+
+LOCAL_INTERMEDIATE_TARGETS += $(rs_generated_src_jar)
+# Make sure the generated resource will be added to the apk.
+LOCAL_RESOURCE_DIR := $(renderscript_intermediate.COMMON)/res $(LOCAL_RESOURCE_DIR)
+endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index f9ed4ef..fc2026c 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -325,12 +325,123 @@
 
 include $(BUILD_SYSTEM)/android_manifest.mk
 
+resource_export_package :=
+
+include $(BUILD_SYSTEM)/java_renderscript.mk
+
+include $(BUILD_SYSTEM)/aapt_flags.mk
+
+ifeq ($(need_compile_res),true)
+
+###############################
+## APK splits
+built_apk_splits :=
+installed_apk_splits :=
+my_apk_split_configs :=
+
+ifdef LOCAL_PACKAGE_SPLITS
+ifdef LOCAL_COMPRESSED_MODULE
+$(error $(LOCAL_MODULE): LOCAL_COMPRESSED_MODULE is not currently supported for split installs)
+endif  # LOCAL_COMPRESSED_MODULE
+
+my_apk_split_configs := $(LOCAL_PACKAGE_SPLITS)
+my_split_suffixes := $(subst $(comma),_,$(my_apk_split_configs))
+built_apk_splits := $(foreach s,$(my_split_suffixes),$(intermediates)/package_$(s).apk)
+endif
+
+$(R_file_stamp) $(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+$(R_file_stamp) $(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
+$(R_file_stamp) $(my_res_package): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
+$(R_file_stamp) $(my_res_package): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
+
+###############################
+## AAPT/AAPT2
+
+ifdef LOCAL_USE_AAPT2
+  my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
+  ifneq (,$(renderscript_target_api))
+    ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
+      my_generated_res_zips := $(rs_generated_res_zip)
+    endif  # renderscript_target_api < 21
+  endif  # renderscript_target_api is set
+  my_asset_dirs := $(LOCAL_ASSET_DIR)
+  my_full_asset_paths := $(all_assets)
+
+  # Add AAPT2 link specific flags.
+  $(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+  ifndef LOCAL_AAPT_NAMESPACES
+    $(my_res_package): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
+  endif
+
+  include $(BUILD_SYSTEM)/aapt2.mk
+else  # LOCAL_USE_AAPT2
+
+  my_srcjar := $(intermediates.COMMON)/aapt.srcjar
+  LOCAL_SRCJARS += $(my_srcjar)
+  $(R_file_stamp): PRIVATE_SRCJAR := $(my_srcjar)
+  $(R_file_stamp): PRIVATE_JAVA_GEN_DIR := $(intermediates.COMMON)/aapt
+  $(R_file_stamp): .KATI_IMPLICIT_OUTPUTS := $(my_srcjar)
+  # Since we don't know where the real R.java file is going to end up,
+  # we need to use another file to stand in its place.  We'll just
+  # copy the generated file to src/R.stamp, which means it will
+  # have the same contents and timestamp as the actual file.
+  #
+  # At the same time, this will copy the R.java file to a central
+  # 'R' directory to make it easier to add the files to an IDE.
+  #
+
+  $(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
+			$(intermediates.COMMON)/public_resources.xml
+  $(R_file_stamp): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
+  $(R_file_stamp): PRIVATE_RESOURCE_LIST := $(all_res_assets)
+  $(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(rs_generated_res_zip) $(AAPT) $(SOONG_ZIP) | $(ACP)
+	@echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
+	@rm -rf $@ && mkdir -p $(dir $@)
+	$(create-resource-java-files)
+	$(call find-generated-R.java,$(PRIVATE_JAVA_GEN_DIR),$@)
+
+  $(proguard_options_file): $(R_file_stamp)
+
+  ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
+    # Put this module's resources into a PRODUCT-agnositc package that
+    # other packages can use to build their own PRODUCT-agnostic R.java (etc.)
+    # files.
+    resource_export_package := $(intermediates.COMMON)/package-export.apk
+    $(R_file_stamp): $(resource_export_package)
+
+    # add-assets-to-package looks at PRODUCT_AAPT_CONFIG, but this target
+    # can't know anything about PRODUCT.  Clear it out just for this target.
+    $(resource_export_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
+    $(resource_export_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
+    $(resource_export_package): PRIVATE_RESOURCE_LIST := $(all_res_assets)
+    $(resource_export_package): $(all_res_assets) $(full_android_manifest) $(RenderScript_file_stamp) $(AAPT)
+	@echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
+	$(create-empty-package)
+	$(add-assets-to-package)
+  endif
+
+endif  # LOCAL_USE_AAPT2
+
+endif  # need_compile_res
+
 called_from_package_internal := true
 #################################
 include $(BUILD_SYSTEM)/java.mk
 #################################
 called_from_package_internal :=
 
+ifeq ($(need_compile_res),true)
+
+# Other modules should depend on the BUILT module if
+# they want to use this module's R.java file.
+$(LOCAL_BUILT_MODULE): $(R_file_stamp)
+
+# The R.java file must exist by the time the java source
+# list is generated
+$(java_source_list_file): $(R_file_stamp)
+
+endif # need_compile_res
+
 LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
 ifeq ($(LOCAL_SDK_RES_VERSION),)
   LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
@@ -367,111 +478,6 @@
 $(full_classes_compiled_jar): $(data_binding_stamp)
 endif  # LOCAL_DATA_BINDING
 
-resource_export_package :=
-
-include $(BUILD_SYSTEM)/aapt_flags.mk
-
-ifeq ($(need_compile_res),true)
-
-###############################
-## APK splits
-built_apk_splits :=
-installed_apk_splits :=
-my_apk_split_configs :=
-
-ifdef LOCAL_PACKAGE_SPLITS
-ifdef LOCAL_COMPRESSED_MODULE
-$(error $(LOCAL_MODULE): LOCAL_COMPRESSED_MODULE is not currently supported for split installs)
-endif  # LOCAL_COMPRESSED_MODULE
-
-my_apk_split_configs := $(LOCAL_PACKAGE_SPLITS)
-my_split_suffixes := $(subst $(comma),_,$(my_apk_split_configs))
-built_apk_splits := $(foreach s,$(my_split_suffixes),$(intermediates)/package_$(s).apk)
-installed_apk_splits := $(foreach s,$(my_split_suffixes),$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
-endif
-
-ifdef LOCAL_USE_AAPT2
-my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
-renderscript_target_api :=
-ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
-renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
-else
-ifneq (,$(LOCAL_SDK_VERSION))
-# Set target-api for LOCAL_SDK_VERSIONs other than current.
-ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
-renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
-endif
-endif  # LOCAL_SDK_VERSION is set
-endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
-ifneq (,$(renderscript_target_api))
-ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
-my_generated_res_dirs := $(rs_generated_res_dir)
-my_generated_res_dirs_deps := $(RenderScript_file_stamp)
-endif  # renderscript_target_api < 21
-endif  # renderscript_target_api is set
-my_asset_dirs := $(LOCAL_ASSET_DIR)
-my_full_asset_paths := $(all_assets)
-
-# Add AAPT2 link specific flags.
-$(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
-ifndef LOCAL_AAPT_NAMESPACES
-  $(my_res_package): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
-endif
-
-include $(BUILD_SYSTEM)/aapt2.mk
-else  # LOCAL_USE_AAPT2
-
-# Since we don't know where the real R.java file is going to end up,
-# we need to use another file to stand in its place.  We'll just
-# copy the generated file to src/R.stamp, which means it will
-# have the same contents and timestamp as the actual file.
-#
-# At the same time, this will copy the R.java file to a central
-# 'R' directory to make it easier to add the files to an IDE.
-#
-
-$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
-			$(intermediates.COMMON)/public_resources.xml
-$(R_file_stamp): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
-$(R_file_stamp): PRIVATE_RESOURCE_LIST := $(all_res_assets)
-$(R_file_stamp): $(all_res_assets) $(full_android_manifest) $(RenderScript_file_stamp) $(AAPT) | $(ACP)
-	@echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
-	@rm -rf $@ && mkdir -p $(dir $@)
-	$(create-resource-java-files)
-	$(call find-generated-R.java,$@)
-
-$(proguard_options_file): $(R_file_stamp)
-
-ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
-# Put this module's resources into a PRODUCT-agnositc package that
-# other packages can use to build their own PRODUCT-agnostic R.java (etc.)
-# files.
-resource_export_package := $(intermediates.COMMON)/package-export.apk
-$(R_file_stamp): $(resource_export_package)
-
-# add-assets-to-package looks at PRODUCT_AAPT_CONFIG, but this target
-# can't know anything about PRODUCT.  Clear it out just for this target.
-$(resource_export_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
-$(resource_export_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
-$(resource_export_package): PRIVATE_RESOURCE_LIST := $(all_res_assets)
-$(resource_export_package): $(all_res_assets) $(full_android_manifest) $(RenderScript_file_stamp) $(AAPT)
-	@echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
-	$(add-assets-to-package)
-endif
-
-endif  # LOCAL_USE_AAPT2
-
-# Other modules should depend on the BUILT module if
-# they want to use this module's R.java file.
-$(LOCAL_BUILT_MODULE): $(R_file_stamp)
-
-# The R.java file must exist by the time the java source
-# list is generated
-$(java_source_list_file): $(R_file_stamp)
-
-endif  # need_compile_res
-
 framework_res_package_export :=
 
 ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
@@ -507,6 +513,14 @@
 $(my_res_package) : $(all_library_res_package_export_deps)
 endif
 
+# These four are set above for $(R_stamp_file) and $(my_res_package), but
+# $(LOCAL_BUILT_MODULE) is not set before java.mk, so they have to be set again
+# here.
+$(LOCAL_BUILT_MODULE): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
+$(LOCAL_BUILT_MODULE): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
+$(LOCAL_BUILT_MODULE): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
+
 ifneq ($(full_classes_jar),)
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
 # Use the jarjar processed arhive as the initial package file.
@@ -673,6 +687,7 @@
 	$(sign-package)
 
 # Rules to install the splits
+installed_apk_splits := $(foreach s,$(my_split_suffixes),$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
 $(installed_apk_splits) : $(my_module_path)/$(LOCAL_MODULE)_%.apk : $(intermediates)/package_%.apk
 	@echo "Install: $@"
 	$(copy-file-to-new-target)
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 309f76b..0afb857 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -95,7 +95,7 @@
 
 all_res_assets := $(all_resources)
 
-include $(BUILD_SYSTEM)/java_library.mk
+include $(BUILD_SYSTEM)/java_renderscript.mk
 
 ifeq (true,$(need_compile_res))
 include $(BUILD_SYSTEM)/android_manifest.mk
@@ -133,10 +133,15 @@
 
 include $(BUILD_SYSTEM)/aapt_flags.mk
 
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
+
 # add --non-constant-id to prevent inlining constants.
 # AAR needs text symbol file R.txt.
 ifdef LOCAL_USE_AAPT2
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib --output-text-symbols $(intermediates.COMMON)/R.txt
 ifndef LOCAL_AAPT_NAMESPACES
   $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
 endif
@@ -144,10 +149,15 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
 else
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --non-constant-id --output-text-symbols $(LOCAL_INTERMEDIATE_SOURCE_DIR)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --non-constant-id --output-text-symbols $(intermediates.COMMON)
+
+my_srcjar := $(intermediates.COMMON)/aapt.srcjar
+LOCAL_SRCJARS += $(my_srcjar)
+$(R_file_stamp): PRIVATE_SRCJAR := $(my_srcjar)
+$(R_file_stamp): PRIVATE_JAVA_GEN_DIR := $(intermediates.COMMON)/aapt
+$(R_file_stamp): .KATI_IMPLICIT_OUTPUTS := $(intermediates.COMMON)/R.txt) $(my_srcjar)
 endif
 
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(LOCAL_INTERMEDIATE_SOURCE_DIR)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_PUBLICS_OUTPUT := $(intermediates.COMMON)/public_resources.xml
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
@@ -159,35 +169,32 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR :=
 
 ifdef LOCAL_USE_AAPT2
-# One more level with name res so we can zip up the flat resources that can be linked by apps.
-my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res/res
-renderscript_target_api :=
-ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
-renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
+  # One more level with name res so we can zip up the flat resources that can be linked by apps.
+  my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res/res
+  ifneq (,$(renderscript_target_api))
+    ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
+      my_generated_res_zips := $(rs_generated_res_zip)
+    endif  # renderscript_target_api < 21
+  endif  # renderscript_target_api is set
+  include $(BUILD_SYSTEM)/aapt2.mk
+  $(my_res_package) : $(framework_res_package_export)
+  $(my_res_package): .KATI_IMPLICIT_OUTPUTS += $(intermediates.COMMON)/R.txt
 else
-ifneq (,$(LOCAL_SDK_VERSION))
-# Set target-api for LOCAL_SDK_VERSIONs other than current.
-ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
-renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
-endif
-endif  # LOCAL_SDK_VERSION is set
-endif  # LOCAL_RENDERSCRIPT_TARGET_API is set
-ifneq (,$(renderscript_target_api))
-ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
-my_generated_res_dirs := $(rs_generated_res_dir)
-my_generated_res_dirs_deps := $(RenderScript_file_stamp)
-endif  # renderscript_target_api < 21
-endif  # renderscript_target_api is set
-include $(BUILD_SYSTEM)/aapt2.mk
-$(my_res_package) : $(framework_res_package_export)
-else
-$(R_file_stamp): PRIVATE_RESOURCE_LIST := $(all_resources)
-$(R_file_stamp) : $(all_resources) $(full_android_manifest) $(AAPT) $(framework_res_package_export)
+  $(R_file_stamp): .KATI_IMPLICIT_OUTPUTS += $(intermediates.COMMON)/R.txt
+  $(R_file_stamp): PRIVATE_RESOURCE_LIST := $(all_resources)
+  $(R_file_stamp) : $(all_resources) $(full_android_manifest) $(AAPT) $(SOONG_ZIP) \
+    $(framework_res_package_export) $(rs_generated_res_zip)
 	@echo "target R.java/Manifest.java: $(PRIVATE_MODULE) ($@)"
 	$(create-resource-java-files)
-	$(hide) find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name R.java | xargs cat > $@
+	$(hide) find $(PRIVATE_JAVA_GEN_DIR) -name R.java | xargs cat > $@
 endif  # LOCAL_USE_AAPT2
 
+endif # need_compile_res
+
+include $(BUILD_SYSTEM)/java_library.mk
+
+ifeq (true,$(need_compile_res))
+
 $(LOCAL_BUILT_MODULE): $(R_file_stamp)
 $(java_source_list_file): $(R_file_stamp)
 $(full_classes_compiled_jar): $(R_file_stamp)
@@ -207,9 +214,9 @@
 $(built_aar): PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
 $(built_aar): PRIVATE_CLASSES_JAR := $(aar_classes_jar)
 $(built_aar): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
-$(built_aar): PRIVATE_R_TXT := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/R.txt
+$(built_aar): PRIVATE_R_TXT := $(intermediates.COMMON)/R.txt
 $(built_aar): $(JAR_ARGS)
-$(built_aar) : $(aar_classes_jar) $(full_android_manifest)
+$(built_aar) : $(aar_classes_jar) $(full_android_manifest) $(intermediates.COMMON)/R.txt
 	@echo "target AAR:  $(PRIVATE_MODULE) ($@)"
 	$(hide) rm -rf $(dir $@)aar && mkdir -p $(dir $@)aar/res
 	$(hide) cp $(PRIVATE_ANDROID_MANIFEST) $(dir $@)aar/AndroidManifest.xml
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 67d019f..7ab9021 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -65,6 +65,17 @@
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
 
+# Wifi.
+BOARD_WLAN_DEVICE           := emulator
+BOARD_HOSTAPD_DRIVER        := NL80211
+BOARD_WPA_SUPPLICANT_DRIVER := NL80211
+BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_simulated
+BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
+WPA_SUPPLICANT_VERSION      := VER_0_8_X
+WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
+WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
+WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
+
 # Enable A/B update
 TARGET_NO_RECOVERY := true
 BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic/sepolicy/createns.te b/target/board/generic/sepolicy/createns.te
new file mode 100644
index 0000000..1eaf9ef
--- /dev/null
+++ b/target/board/generic/sepolicy/createns.te
@@ -0,0 +1,14 @@
+# Network namespace creation
+type createns, domain;
+type createns_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(createns)
+
+allow createns self:capability { sys_admin net_raw setuid setgid };
+allow createns varrun_file:dir { add_name search write };
+allow createns varrun_file:file { create mounton open read write };
+
+#Allow createns itself to be run by init in its own domain
+domain_auto_trans(goldfish_setup, createns_exec, createns);
+allow createns goldfish_setup:fd use;
+
diff --git a/target/board/generic/sepolicy/dhcpclient.te b/target/board/generic/sepolicy/dhcpclient.te
new file mode 100644
index 0000000..df71fca
--- /dev/null
+++ b/target/board/generic/sepolicy/dhcpclient.te
@@ -0,0 +1,20 @@
+# DHCP client
+type dhcpclient, domain;
+type dhcpclient_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(dhcpclient)
+net_domain(dhcpclient)
+
+allow dhcpclient execns:fd use;
+
+set_prop(dhcpclient, net_eth0_prop);
+allow dhcpclient self:capability { net_admin net_raw };
+allow dhcpclient self:udp_socket create;
+allow dhcpclient self:netlink_route_socket { write nlmsg_write };
+allow dhcpclient varrun_file:dir search;
+allow dhcpclient self:packet_socket { create bind write read };
+allowxperm dhcpclient self:udp_socket ioctl { SIOCSIFFLAGS
+                                              SIOCSIFADDR
+                                              SIOCSIFNETMASK
+                                              SIOCSIFMTU
+                                              SIOCGIFHWADDR };
diff --git a/target/board/generic/sepolicy/dhcpserver.te b/target/board/generic/sepolicy/dhcpserver.te
new file mode 100644
index 0000000..7e8ba26
--- /dev/null
+++ b/target/board/generic/sepolicy/dhcpserver.te
@@ -0,0 +1,12 @@
+# DHCP server
+type dhcpserver, domain;
+type dhcpserver_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(dhcpserver)
+net_domain(dhcpserver)
+
+allow dhcpserver execns:fd use;
+
+get_prop(dhcpserver, net_eth0_prop);
+allow dhcpserver self:udp_socket { ioctl create setopt bind };
+allow dhcpserver self:capability { net_raw net_bind_service };
diff --git a/target/board/generic/sepolicy/execns.te b/target/board/generic/sepolicy/execns.te
new file mode 100644
index 0000000..9675a99
--- /dev/null
+++ b/target/board/generic/sepolicy/execns.te
@@ -0,0 +1,34 @@
+# Network namespace transitions
+type execns, domain;
+type execns_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(execns)
+
+allow execns varrun_file:dir search;
+allow execns varrun_file:file r_file_perms;
+allow execns self:capability sys_admin;
+allow execns nsfs:file { open read };
+
+#Allow execns itself to be run by init in its own domain
+domain_auto_trans(init, execns_exec, execns);
+
+# Allow dhcpclient to be run by execns in its own domain
+domain_auto_trans(execns, dhcpclient_exec, dhcpclient);
+
+# Allow dhcpserver to be run by execns in its own domain
+domain_auto_trans(execns, dhcpserver_exec, dhcpserver);
+
+# Rules to allow execution of hostapd and allow it to run
+allow execns hal_wifi_hostapd_default_exec:file { execute_no_trans };
+allow execns self:capability { net_admin net_raw };
+allow execns self:netlink_generic_socket { bind create getattr read setopt write };
+allow execns self:netlink_route_socket { bind create read write nlmsg_write };
+allow execns execns:udp_socket { create ioctl };
+allow execns self:packet_socket { create setopt };
+allow execns sysfs_net:dir { search };
+allowxperm execns self:udp_socket ioctl priv_sock_ioctls;
+
+# Allow execns to read createns proc file to get the namespace file
+allow execns createns:file read;
+allow execns createns:dir search;
+allow execns createns:lnk_file read;
diff --git a/target/board/generic/sepolicy/file.te b/target/board/generic/sepolicy/file.te
new file mode 100644
index 0000000..b0aa217
--- /dev/null
+++ b/target/board/generic/sepolicy/file.te
@@ -0,0 +1,4 @@
+type sysfs_writable, fs_type, sysfs_type, mlstrustedobject;
+type varrun_file, file_type, data_file_type, mlstrustedobject;
+type mediadrm_vendor_data_file, file_type, data_file_type;
+type nsfs, fs_type;
diff --git a/target/board/generic/sepolicy/file_contexts b/target/board/generic/sepolicy/file_contexts
index 521c65e..73fe752 100644
--- a/target/board/generic/sepolicy/file_contexts
+++ b/target/board/generic/sepolicy/file_contexts
@@ -17,7 +17,13 @@
 /dev/ttyS2                   u:object_r:console_device:s0
 /vendor/bin/init\.ranchu-core\.sh u:object_r:goldfish_setup_exec:s0
 /vendor/bin/init\.ranchu-net\.sh u:object_r:goldfish_setup_exec:s0
+/vendor/bin/init\.wifi\.sh   u:object_r:goldfish_setup_exec:s0
 /vendor/bin/qemu-props       u:object_r:qemu_props_exec:s0
+/vendor/bin/createns         u:object_r:createns_exec:s0
+/vendor/bin/execns           u:object_r:execns_exec:s0
+/vendor/bin/ipv6proxy        u:object_r:ipv6proxy_exec:s0
+/vendor/bin/dhcpclient       u:object_r:dhcpclient_exec:s0
+/vendor/bin/dhcpserver       u:object_r:dhcpserver_exec:s0
 
 /vendor/bin/hw/android\.hardware\.drm@1\.0-service\.widevine          u:object_r:hal_drm_widevine_exec:s0
 
@@ -33,3 +39,8 @@
 /vendor/lib(64)?/lib_renderControl_enc\.so       u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libGLESv1_enc\.so       u:object_r:same_process_hal_file:s0
 /vendor/lib(64)?/libGLESv2_enc\.so       u:object_r:same_process_hal_file:s0
+
+# data
+/data/vendor/mediadrm(/.*)?            u:object_r:mediadrm_vendor_data_file:s0
+/data/vendor/var/run(/.*)?             u:object_r:varrun_file:s0
+
diff --git a/target/board/generic/sepolicy/genfs_contexts b/target/board/generic/sepolicy/genfs_contexts
index 91cedf1..1b81626 100644
--- a/target/board/generic/sepolicy/genfs_contexts
+++ b/target/board/generic/sepolicy/genfs_contexts
@@ -15,3 +15,6 @@
 genfscon sysfs /devices/pci0000:00/0000:00:08.0/virtio5/net u:object_r:sysfs_net:s0
 genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim0/net u:object_r:sysfs_net:s0
 genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim1/net u:object_r:sysfs_net:s0
+
+# /proc/<pid>/ns
+genfscon nsfs / u:object_r:nsfs:s0
diff --git a/target/board/generic/sepolicy/goldfish_setup.te b/target/board/generic/sepolicy/goldfish_setup.te
index eb913e9..1492cbd 100644
--- a/target/board/generic/sepolicy/goldfish_setup.te
+++ b/target/board/generic/sepolicy/goldfish_setup.te
@@ -11,3 +11,35 @@
 allowxperm goldfish_setup self:udp_socket ioctl priv_sock_ioctls;
 wakelock_use(goldfish_setup);
 allow goldfish_setup vendor_shell_exec:file { rx_file_perms };
+
+# Set system properties to start services
+set_prop(goldfish_setup, ctl_default_prop);
+
+# Set up WiFi
+allow goldfish_setup self:netlink_route_socket { create nlmsg_write setopt bind getattr read write nlmsg_read };
+allow goldfish_setup self:netlink_generic_socket create_socket_perms_no_ioctl;
+allow goldfish_setup self:capability { sys_module sys_admin };
+allow goldfish_setup varrun_file:dir { mounton open read write add_name search remove_name };
+allow goldfish_setup varrun_file:file { mounton getattr create read write open unlink };
+allow goldfish_setup execns_exec:file rx_file_perms;
+allow goldfish_setup proc_net:file rw_file_perms;
+allow goldfish_setup proc:file r_file_perms;
+set_prop(goldfish_setup, ctl_default_prop);
+allow goldfish_setup nsfs:file r_file_perms;
+allow goldfish_setup system_data_file:dir getattr;
+allow goldfish_setup kernel:system module_request;
+# Allow goldfish_setup to run /system/bin/ip and /system/bin/iw
+allow goldfish_setup system_file:file execute_no_trans;
+# Allow goldfish_setup to run init.wifi.sh
+allow goldfish_setup goldfish_setup_exec:file execute_no_trans;
+#Allow goldfish_setup to run createns in its own domain
+domain_auto_trans(goldfish_setup, createns_exec, createns);
+# iw
+allow goldfish_setup sysfs:file { read open };
+# iptables
+allow goldfish_setup system_file:file lock;
+allow goldfish_setup self:rawip_socket { create getopt setopt };
+# Allow goldfish_setup to read createns proc file to get the namespace file
+allow goldfish_setup createns:file { read };
+allow goldfish_setup createns:dir { search };
+allow goldfish_setup createns:lnk_file { read };
diff --git a/target/board/generic/sepolicy/hal_drm_widevine.te b/target/board/generic/sepolicy/hal_drm_widevine.te
index 42d462a..d49000d 100644
--- a/target/board/generic/sepolicy/hal_drm_widevine.te
+++ b/target/board/generic/sepolicy/hal_drm_widevine.te
@@ -10,3 +10,5 @@
 
 vndbinder_use(hal_drm_widevine);
 hal_client_domain(hal_drm_widevine, hal_graphics_composer);
+allow hal_drm_widevine mediadrm_vendor_data_file:dir create_dir_perms;
+allow hal_drm_widevine mediadrm_vendor_data_file:file create_file_perms;
diff --git a/target/board/generic/sepolicy/hal_wifi_default.te b/target/board/generic/sepolicy/hal_wifi_default.te
new file mode 100644
index 0000000..de4b996
--- /dev/null
+++ b/target/board/generic/sepolicy/hal_wifi_default.te
@@ -0,0 +1 @@
+allow hal_wifi_default hal_wifi_default:netlink_route_socket { create bind write read nlmsg_read };
diff --git a/target/board/generic/sepolicy/ipv6proxy.te b/target/board/generic/sepolicy/ipv6proxy.te
new file mode 100644
index 0000000..22976fe
--- /dev/null
+++ b/target/board/generic/sepolicy/ipv6proxy.te
@@ -0,0 +1,16 @@
+# IPv6 proxying
+type ipv6proxy, domain;
+type ipv6proxy_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(ipv6proxy)
+net_domain(ipv6proxy)
+
+# Allow ipv6proxy to be run by execns in its own domain
+domain_auto_trans(execns, ipv6proxy_exec, ipv6proxy);
+allow ipv6proxy execns:fd use;
+
+allow ipv6proxy self:capability { sys_admin sys_module net_admin net_raw };
+allow ipv6proxy self:packet_socket { bind create read };
+allow ipv6proxy self:netlink_route_socket nlmsg_write;
+allow ipv6proxy varrun_file:dir search;
+allowxperm ipv6proxy self:udp_socket ioctl { SIOCSIFFLAGS SIOCGIFHWADDR };
diff --git a/target/board/generic/sepolicy/property.te b/target/board/generic/sepolicy/property.te
index 56e02ef..8c7c892 100644
--- a/target/board/generic/sepolicy/property.te
+++ b/target/board/generic/sepolicy/property.te
@@ -1,3 +1,4 @@
 type qemu_prop, property_type;
 type qemu_cmdline, property_type;
 type radio_noril_prop, property_type;
+type net_eth0_prop, property_type;
diff --git a/target/board/generic/sepolicy/property_contexts b/target/board/generic/sepolicy/property_contexts
index 3a61b6b..c5a2bc1 100644
--- a/target/board/generic/sepolicy/property_contexts
+++ b/target/board/generic/sepolicy/property_contexts
@@ -3,3 +3,4 @@
 ro.emu.                 u:object_r:qemu_prop:s0
 ro.emulator.            u:object_r:qemu_prop:s0
 ro.radio.noril          u:object_r:radio_noril_prop:s0
+net.eth0.               u:object_r:net_eth0_prop:s0
diff --git a/target/board/generic/sepolicy/radio.te b/target/board/generic/sepolicy/radio.te
new file mode 100644
index 0000000..742d3b2
--- /dev/null
+++ b/target/board/generic/sepolicy/radio.te
@@ -0,0 +1,3 @@
+# Allow the radio to read these properties, they only have an SELinux label in
+# the emulator.
+get_prop(radio, net_eth0_prop);
diff --git a/target/board/generic/sepolicy/rild.te b/target/board/generic/sepolicy/rild.te
new file mode 100644
index 0000000..ea18373
--- /dev/null
+++ b/target/board/generic/sepolicy/rild.te
@@ -0,0 +1,3 @@
+# Allow rild to read these properties, they only have an SELinux label in the
+# emulator.
+get_prop(rild, net_eth0_prop);
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index e066e3a..d5f79f4 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -96,6 +96,17 @@
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
 BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
 
+# Wifi.
+BOARD_WLAN_DEVICE           := emulator
+BOARD_HOSTAPD_DRIVER        := NL80211
+BOARD_WPA_SUPPLICANT_DRIVER := NL80211
+BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_simulated
+BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
+WPA_SUPPLICANT_VERSION      := VER_0_8_X
+WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
+WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
+WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
+
 # Enable A/B update
 TARGET_NO_RECOVERY := true
 BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index d1cbeb9..2d00506 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -67,3 +67,14 @@
 # Enable A/B update
 TARGET_NO_RECOVERY := true
 BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+
+# Wifi.
+BOARD_WLAN_DEVICE           := emulator
+BOARD_HOSTAPD_DRIVER        := NL80211
+BOARD_WPA_SUPPLICANT_DRIVER := NL80211
+BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_simulated
+BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
+WPA_SUPPLICANT_VERSION      := VER_0_8_X
+WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
+WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
+WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index a9c5142..5377fb1 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -62,6 +62,17 @@
 
 BOARD_VNDK_VERSION := current
 
+# Wifi.
+BOARD_WLAN_DEVICE           := emulator
+BOARD_HOSTAPD_DRIVER        := NL80211
+BOARD_WPA_SUPPLICANT_DRIVER := NL80211
+BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_simulated
+BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
+WPA_SUPPLICANT_VERSION      := VER_0_8_X
+WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
+WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
+WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
+
 # Enable A/B update
 TARGET_NO_RECOVERY := true
 BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
index 67ebe04..11466b8 100644
--- a/target/product/emulator.mk
+++ b/target/product/emulator.mk
@@ -55,6 +55,7 @@
     audio.primary.goldfish \
     audio.primary.goldfish_legacy \
     android.hardware.audio@2.0-service \
+    android.hardware.wifi@1.0-service \
     vibrator.goldfish \
     power.goldfish \
     power.ranchu \
@@ -116,9 +117,23 @@
 PRODUCT_PACKAGES += \
     vndk-sp
 
+# WiFi
+PRODUCT_PACKAGES += \
+	createns \
+	dhcpclient \
+	dhcpserver \
+	execns \
+	hostapd \
+	ip \
+	ipv6proxy \
+	iw \
+	wificond \
+	wpa_supplicant \
+
 PRODUCT_COPY_FILES += \
     device/generic/goldfish/init.ranchu-core.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.ranchu-core.sh \
     device/generic/goldfish/init.ranchu-net.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.ranchu-net.sh \
+    device/generic/goldfish/wifi/init.wifi.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.wifi.sh \
     device/generic/goldfish/init.ranchu.rc:root/init.ranchu.rc \
     device/generic/goldfish/fstab.ranchu:root/fstab.ranchu \
     device/generic/goldfish/fstab.ranchu.early:root/fstab.ranchu.early \
@@ -127,6 +142,9 @@
     device/generic/goldfish/manifest.xml:$(TARGET_COPY_OUT_VENDOR)/manifest.xml \
     device/generic/goldfish/data/etc/permissions/privapp-permissions-goldfish.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/privapp-permissions-goldfish.xml \
     device/generic/goldfish/data/etc/config.ini:config.ini \
+    device/generic/goldfish/wifi/simulated_hostapd.conf:$(TARGET_COPY_OUT_VENDOR)/etc/simulated_hostapd.conf \
+    device/generic/goldfish/wifi/wpa_supplicant.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant.conf \
+    device/generic/goldfish/wifi/WifiConfigStore.xml:data/misc/wifi/WifiConfigStore.xml \
     frameworks/native/data/etc/android.hardware.wifi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.xml
 
 PRODUCT_PACKAGE_OVERLAYS := device/generic/goldfish/overlay
diff --git a/target/product/sdk_base.mk b/target/product/sdk_base.mk
index df68d02..e3f2db2 100644
--- a/target/product/sdk_base.mk
+++ b/target/product/sdk_base.mk
@@ -44,7 +44,7 @@
 	SysuiDarkThemeOverlay \
 	EasterEgg \
 	WallpaperPicker \
-	WidgetPreview
+	WidgetPreview \
 
 # Define the host tools and libs that are parts of the SDK.
 -include sdk/build/product_sdk.mk
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 3579645..1e2f39e 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1024,6 +1024,9 @@
     """
     return self._GetPropertyFilesString(input_zip, reserve_space=True)
 
+  class InsufficientSpaceException(Exception):
+    pass
+
   def Finalize(self, input_zip, reserved_length):
     """Finalizes a property-files string with actual METADATA offset/size info.
 
@@ -1045,13 +1048,15 @@
       "payload.bin:679:343,payload_properties.txt:378:45,metadata:69:379  ".
 
     Raises:
-      AssertionError: If the reserved length is insufficient to hold the final
-          string.
+      InsufficientSpaceException: If the reserved length is insufficient to hold
+          the final string.
     """
     result = self._GetPropertyFilesString(input_zip, reserve_space=False)
-    assert len(result) <= reserved_length, \
-        'Insufficient reserved space: reserved={}, actual={}'.format(
-            reserved_length, len(result))
+    if len(result) > reserved_length:
+      raise self.InsufficientSpaceException(
+          'Insufficient reserved space: reserved={}, actual={}'.format(
+              reserved_length, len(result)))
+
     result += ' ' * (reserved_length - len(result))
     return result
 
@@ -1089,11 +1094,12 @@
 
     # 'META-INF/com/android/metadata' is required. We don't know its actual
     # offset and length (as well as the values for other entries). So we reserve
-    # 10-byte as a placeholder, which is to cover the space for metadata entry
-    # ('xx:xxx', since it's ZIP_STORED which should appear at the beginning of
-    # the zip), as well as the possible value changes in other entries.
+    # 15-byte as a placeholder ('offset:length'), which is sufficient to cover
+    # the space for metadata entry. Because 'offset' allows a max of 10-digit
+    # (i.e. ~9 GiB), with a max of 4-digit for the length. Note that all the
+    # reserved space serves the metadata entry only.
     if reserve_space:
-      tokens.append('metadata:' + ' ' * 10)
+      tokens.append('metadata:' + ' ' * 15)
     else:
       tokens.append(ComputeEntryOffsetSize(METADATA_NAME))
 
@@ -1252,36 +1258,54 @@
     output_file: The final output ZIP filename.
     needed_property_files: The list of PropertyFiles' to be generated.
   """
-  output_zip = zipfile.ZipFile(
-      input_file, 'a', compression=zipfile.ZIP_DEFLATED)
 
-  # Write the current metadata entry with placeholders.
-  for property_files in needed_property_files:
-    metadata[property_files.name] = property_files.Compute(output_zip)
-  WriteMetadata(metadata, output_zip)
-  common.ZipClose(output_zip)
+  def ComputeAllPropertyFiles(input_file, needed_property_files):
+    # Write the current metadata entry with placeholders.
+    with zipfile.ZipFile(input_file) as input_zip:
+      for property_files in needed_property_files:
+        metadata[property_files.name] = property_files.Compute(input_zip)
+      namelist = input_zip.namelist()
 
-  # SignOutput(), which in turn calls signapk.jar, will possibly reorder the
-  # ZIP entries, as well as padding the entry headers. We do a preliminary
-  # signing (with an incomplete metadata entry) to allow that to happen. Then
-  # compute the ZIP entry offsets, write back the final metadata and do the
-  # final signing.
-  if OPTIONS.no_signing:
-    prelim_signing = input_file
-  else:
+    if METADATA_NAME in namelist:
+      common.ZipDelete(input_file, METADATA_NAME)
+    output_zip = zipfile.ZipFile(input_file, 'a')
+    WriteMetadata(metadata, output_zip)
+    common.ZipClose(output_zip)
+
+    if OPTIONS.no_signing:
+      return input_file
+
     prelim_signing = common.MakeTempFile(suffix='.zip')
     SignOutput(input_file, prelim_signing)
+    return prelim_signing
 
-  # Open the signed zip. Compute the final metadata that's needed for streaming.
-  with zipfile.ZipFile(prelim_signing, 'r') as prelim_signing_zip:
-    for property_files in needed_property_files:
-      metadata[property_files.name] = property_files.Finalize(
-          prelim_signing_zip, len(metadata[property_files.name]))
+  def FinalizeAllPropertyFiles(prelim_signing, needed_property_files):
+    with zipfile.ZipFile(prelim_signing) as prelim_signing_zip:
+      for property_files in needed_property_files:
+        metadata[property_files.name] = property_files.Finalize(
+            prelim_signing_zip, len(metadata[property_files.name]))
+
+  # SignOutput(), which in turn calls signapk.jar, will possibly reorder the ZIP
+  # entries, as well as padding the entry headers. We do a preliminary signing
+  # (with an incomplete metadata entry) to allow that to happen. Then compute
+  # the ZIP entry offsets, write back the final metadata and do the final
+  # signing.
+  prelim_signing = ComputeAllPropertyFiles(input_file, needed_property_files)
+  try:
+    FinalizeAllPropertyFiles(prelim_signing, needed_property_files)
+  except PropertyFiles.InsufficientSpaceException:
+    # Even with the preliminary signing, the entry orders may change
+    # dramatically, which leads to insufficiently reserved space during the
+    # first call to ComputeAllPropertyFiles(). In that case, we redo all the
+    # preliminary signing works, based on the already ordered ZIP entries, to
+    # address the issue.
+    prelim_signing = ComputeAllPropertyFiles(
+        prelim_signing, needed_property_files)
+    FinalizeAllPropertyFiles(prelim_signing, needed_property_files)
 
   # Replace the METADATA entry.
   common.ZipDelete(prelim_signing, METADATA_NAME)
-  output_zip = zipfile.ZipFile(
-      prelim_signing, 'a', compression=zipfile.ZIP_DEFLATED)
+  output_zip = zipfile.ZipFile(prelim_signing, 'a')
   WriteMetadata(metadata, output_zip)
   common.ZipClose(output_zip)
 
@@ -1292,7 +1316,7 @@
     SignOutput(prelim_signing, output_file)
 
   # Reopen the final signed zip to double check the streaming metadata.
-  with zipfile.ZipFile(output_file, 'r') as output_zip:
+  with zipfile.ZipFile(output_file) as output_zip:
     for property_files in needed_property_files:
       property_files.Verify(output_zip, metadata[property_files.name].strip())
 
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 97687e7..d7cace8 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -24,8 +24,8 @@
 import common
 import test_utils
 from ota_from_target_files import (
-    _LoadOemDicts, AbOtaPropertyFiles, BuildInfo, GetPackageMetadata,
-    GetTargetFilesZipForSecondaryImages,
+    _LoadOemDicts, AbOtaPropertyFiles, BuildInfo, FinalizeMetadata,
+    GetPackageMetadata, GetTargetFilesZipForSecondaryImages,
     GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
     Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
     StreamingPropertyFiles, WriteFingerprintAssertion)
@@ -373,11 +373,22 @@
   }
 
   def setUp(self):
+    self.testdata_dir = test_utils.get_testdata_dir()
+    self.assertTrue(os.path.exists(self.testdata_dir))
+
     # Reset the global options as in ota_from_target_files.py.
     common.OPTIONS.incremental_source = None
     common.OPTIONS.downgrade = False
     common.OPTIONS.timestamp = False
     common.OPTIONS.wipe_user_data = False
+    common.OPTIONS.no_signing = False
+    common.OPTIONS.package_key = os.path.join(self.testdata_dir, 'testkey')
+    common.OPTIONS.key_passwords = {
+        common.OPTIONS.package_key : None,
+    }
+
+    common.OPTIONS.search_path = test_utils.get_search_path()
+    self.assertIsNotNone(common.OPTIONS.search_path)
 
   def tearDown(self):
     common.Cleanup()
@@ -590,6 +601,68 @@
     with zipfile.ZipFile(target_file) as verify_zip:
       self.assertNotIn(POSTINSTALL_CONFIG, verify_zip.namelist())
 
+  def _test_FinalizeMetadata(self, large_entry=False):
+    entries = [
+        'required-entry1',
+        'required-entry2',
+    ]
+    zip_file = PropertyFilesTest.construct_zip_package(entries)
+    # Add a large entry of 1 GiB if requested.
+    if large_entry:
+      with zipfile.ZipFile(zip_file, 'a') as zip_fp:
+        zip_fp.writestr(
+            # Using 'zoo' so that the entry stays behind others after signing.
+            'zoo',
+            'A' * 1024 * 1024 * 1024,
+            zipfile.ZIP_STORED)
+
+    metadata = {}
+    output_file = common.MakeTempFile(suffix='.zip')
+    needed_property_files = (
+        TestPropertyFiles(),
+    )
+    FinalizeMetadata(metadata, zip_file, output_file, needed_property_files)
+    self.assertIn('ota-test-property-files', metadata)
+
+  def test_FinalizeMetadata(self):
+    self._test_FinalizeMetadata()
+
+  def test_FinalizeMetadata_withNoSigning(self):
+    common.OPTIONS.no_signing = True
+    self._test_FinalizeMetadata()
+
+  def test_FinalizeMetadata_largeEntry(self):
+    self._test_FinalizeMetadata(large_entry=True)
+
+  def test_FinalizeMetadata_largeEntry_withNoSigning(self):
+    common.OPTIONS.no_signing = True
+    self._test_FinalizeMetadata(large_entry=True)
+
+  def test_FinalizeMetadata_insufficientSpace(self):
+    entries = [
+        'required-entry1',
+        'required-entry2',
+        'optional-entry1',
+        'optional-entry2',
+    ]
+    zip_file = PropertyFilesTest.construct_zip_package(entries)
+    with zipfile.ZipFile(zip_file, 'a') as zip_fp:
+      zip_fp.writestr(
+          # 'foo-entry1' will appear ahead of all other entries (in alphabetical
+          # order) after the signing, which will in turn trigger the
+          # InsufficientSpaceException and an automatic retry.
+          'foo-entry1',
+          'A' * 1024 * 1024,
+          zipfile.ZIP_STORED)
+
+    metadata = {}
+    needed_property_files = (
+        TestPropertyFiles(),
+    )
+    output_file = common.MakeTempFile(suffix='.zip')
+    FinalizeMetadata(metadata, zip_file, output_file, needed_property_files)
+    self.assertIn('ota-test-property-files', metadata)
+
 
 class TestPropertyFiles(PropertyFiles):
   """A class that extends PropertyFiles for testing purpose."""
@@ -609,11 +682,14 @@
 
 class PropertyFilesTest(unittest.TestCase):
 
+  def setUp(self):
+    common.OPTIONS.no_signing = False
+
   def tearDown(self):
     common.Cleanup()
 
   @staticmethod
-  def _construct_zip_package(entries):
+  def construct_zip_package(entries):
     zip_file = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(zip_file, 'w') as zip_fp:
       for entry in entries:
@@ -647,7 +723,7 @@
         'required-entry1',
         'required-entry2',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       property_files_string = property_files.Compute(zip_fp)
@@ -663,7 +739,7 @@
         'optional-entry1',
         'optional-entry2',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       property_files_string = property_files.Compute(zip_fp)
@@ -676,7 +752,7 @@
     entries = (
         'required-entry2',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       self.assertRaises(KeyError, property_files.Compute, zip_fp)
@@ -687,7 +763,7 @@
         'required-entry2',
         'META-INF/com/android/metadata',
     ]
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # pylint: disable=protected-access
@@ -710,7 +786,7 @@
         'optional-entry2',
         'META-INF/com/android/metadata',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
@@ -725,7 +801,7 @@
 
       # Or pass in insufficient length.
       self.assertRaises(
-          AssertionError,
+          PropertyFiles.InsufficientSpaceException,
           property_files.Finalize,
           zip_fp,
           raw_length - 1)
@@ -745,7 +821,7 @@
         'optional-entry2',
         'META-INF/com/android/metadata',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
@@ -787,7 +863,7 @@
         'care_map.txt',
         'compatibility.zip',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       property_files_string = property_files.Compute(zip_fp)
@@ -804,7 +880,7 @@
         'compatibility.zip',
         'META-INF/com/android/metadata',
     ]
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # pylint: disable=protected-access
@@ -827,7 +903,7 @@
         'compatibility.zip',
         'META-INF/com/android/metadata',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
@@ -923,8 +999,8 @@
       self.assertEqual(verify_fp.read(), metadata_signature)
 
   @staticmethod
-  def _construct_zip_package_withValidPayload(with_metadata=False):
-    # Cannot use _construct_zip_package() since we need a "valid" payload.bin.
+  def construct_zip_package_withValidPayload(with_metadata=False):
+    # Cannot use construct_zip_package() since we need a "valid" payload.bin.
     target_file = construct_target_files()
     payload = Payload()
     payload.Generate(target_file)
@@ -951,7 +1027,7 @@
     return zip_file
 
   def test_Compute(self):
-    zip_file = self._construct_zip_package_withValidPayload()
+    zip_file = self.construct_zip_package_withValidPayload()
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       property_files_string = property_files.Compute(zip_fp)
@@ -964,7 +1040,7 @@
         zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
 
   def test_Finalize(self):
-    zip_file = self._construct_zip_package_withValidPayload(with_metadata=True)
+    zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # pylint: disable=protected-access
@@ -980,7 +1056,7 @@
         zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
 
   def test_Verify(self):
-    zip_file = self._construct_zip_package_withValidPayload(with_metadata=True)
+    zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # pylint: disable=protected-access
@@ -1001,7 +1077,7 @@
 
   def test_Compute(self):
     entries = ()
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
       property_files_string = property_files.Compute(zip_fp)
@@ -1014,7 +1090,7 @@
     entries = [
         'META-INF/com/android/metadata',
     ]
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
       # pylint: disable=protected-access
@@ -1032,7 +1108,7 @@
     entries = (
         'META-INF/com/android/metadata',
     )
-    zip_file = self._construct_zip_package(entries)
+    zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
       # pylint: disable=protected-access
diff --git a/tools/releasetools/test_utils.py b/tools/releasetools/test_utils.py
index e64355b..a15ff5b 100644
--- a/tools/releasetools/test_utils.py
+++ b/tools/releasetools/test_utils.py
@@ -32,6 +32,22 @@
   return os.path.join(current_dir, 'testdata')
 
 
+def get_search_path():
+  """Returns the search path that has 'framework/signapk.jar' under."""
+  current_dir = os.path.dirname(os.path.realpath(__file__))
+  for path in (
+      # In relative to 'build/make/tools/releasetools' in the Android source.
+      ['..'] * 4 + ['out', 'host', 'linux-x86'],
+      # Or running the script unpacked from otatools.zip.
+      ['..']):
+    full_path = os.path.realpath(os.path.join(current_dir, *path))
+    signapk_path = os.path.realpath(
+        os.path.join(full_path, 'framework', 'signapk.jar'))
+    if os.path.exists(signapk_path):
+      return full_path
+  return None
+
+
 def construct_sparse_image(chunks):
   """Returns a sparse image file constructed from the given chunks.