Merge "Deprecate implicit make rules"
diff --git a/core/Makefile b/core/Makefile
index 38ee46c..a5109f0 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -36,9 +36,7 @@
             $(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))),\
             $(if $(and $(filter %.jar,$(_dest)),$(filter $(basename $(notdir $(_dest))),$(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))),\
                 $(eval $(call copy-and-uncompress-dexs,$(_src),$(_fulldest))), \
-                $(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init,$(dir $(_dest))),\
-                    $(eval $(call copy-init-script-file-checked,$(_src),$(_fulldest))),\
-                    $(eval $(call copy-one-file,$(_src),$(_fulldest)))))) \
+                $(eval $(call copy-one-file,$(_src),$(_fulldest))))) \
         $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) \
         $(eval unique_product_copy_files_destinations += $(_dest))))
 
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 0215106..3af81ff 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -18,18 +18,14 @@
 ifndef LOCAL_DONT_MERGE_MANIFESTS
   my_full_libs_manifest_files += $(LOCAL_FULL_LIBS_MANIFEST_FILES)
 
-  ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
-    my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
-      $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
-  endif
+  my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES) $(LOCAL_STATIC_ANDROID_LIBRARIES),\
+    $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/manifest/AndroidManifest.xml)
 endif
 
-ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
-  # With aapt2, we'll link in the built resource from the AAR.
-  ifneq ($(LOCAL_USE_AAPT2),true)
-    LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
-      $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
-  endif
+# With aapt2, we'll link in the built resource from the AAR.
+ifneq ($(LOCAL_USE_AAPT2),true)
+  LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+    $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
 endif
 
 full_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 4f157cb..4f0e39f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -424,7 +424,7 @@
 # Make sure we only set up the copy rules once, even if another arch variant
 # shares a common LOCAL_INIT_RC.
 my_init_rc_new_pairs := $(filter-out $(ALL_INIT_RC_INSTALLED_PAIRS),$(my_init_rc_pairs))
-my_init_rc_new_installed := $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
+my_init_rc_new_installed := $(call copy-many-files,$(my_init_rc_new_pairs))
 ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
 
 $(my_all_targets) : $(my_init_rc_installed)
diff --git a/core/config.mk b/core/config.mk
index 7bbb3e5..0920b56 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -615,7 +615,6 @@
 CKATI := $(prebuilt_build_tools_bin)/ckati
 DEPMOD := $(HOST_OUT_EXECUTABLES)/depmod
 FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist
-HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier
 MAKEPARALLEL := $(prebuilt_build_tools_bin)/makeparallel
 SOONG_JAVAC_WRAPPER := $(SOONG_HOST_OUT_EXECUTABLES)/soong_javac_wrapper
 SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip
diff --git a/core/definitions.mk b/core/definitions.mk
index 9d4c532..a8d7b2d 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2658,28 +2658,6 @@
     $(_cmf_dest)))
 endef
 
-# Copy the file only if it's a well-formed init script file. For use via $(eval).
-# $(1): source file
-# $(2): destination file
-define copy-init-script-file-checked
-$(2): $(1) $(HOST_INIT_VERIFIER) $(call intermediates-dir-for,ETC,passwd)/passwd
-	@echo "Copy init script: $$@"
-	$(hide) $(HOST_INIT_VERIFIER) $$< $(call intermediates-dir-for,ETC,passwd)/passwd
-	$$(copy-file-to-target)
-endef
-
-# Copies many init script files and check they are well-formed.
-# $(1): The init script files to copy.  Each entry is a ':' separated src:dst pair.
-# Evaluates to the list of the dst files. (ie suitable for a dependency list.)
-define copy-many-init-script-files-checked
-$(foreach f, $(1), $(strip \
-    $(eval _cmf_tuple := $(subst :, ,$(f))) \
-    $(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
-    $(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
-    $(eval $(call copy-init-script-file-checked,$(_cmf_src),$(_cmf_dest))) \
-    $(_cmf_dest)))
-endef
-
 # Copy the file only if it's a well-formed xml file. For use via $(eval).
 # $(1): source file
 # $(2): destination file, must end with .xml.
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 1a5b389..17dd046 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -508,13 +508,10 @@
 endif # LOCAL_DEX_PREOPT
 
 else  # ! prebuilt_module_is_dex_javalib
-ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init,$(dir $(LOCAL_INSTALLED_MODULE))),)
-  $(eval $(call copy-init-script-file-checked,$(my_prebuilt_src_file),$(built_module)))
-else ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
 $(built_module) : $(my_prebuilt_src_file)
+ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
 	$(transform-prebuilt-to-target-strip-comments)
 else
-$(built_module) : $(my_prebuilt_src_file)
 	$(transform-prebuilt-to-target)
 endif
 ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
@@ -598,6 +595,10 @@
 	$(hide) touch $(dir $@)/proguard.txt
 	$(hide) touch $(dir $@)/AndroidManifest.xml
 
+my_prebuilt_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+$(eval $(call copy-one-file,$(my_src_android_manifest),$(my_prebuilt_android_manifest)))
+$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_prebuilt_android_manifest))
+
 endif
 
 $(common_classes_jar) : $(my_src_jar)
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index eeaab31..0ba2c7a 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -64,6 +64,10 @@
   my_static_library_extra_packages := $(intermediates.COMMON)/extra_packages
   $(eval $(call copy-one-file,$(LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES),$(my_static_library_extra_packages)))
   $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_extra_packages))
+
+  my_static_library_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+  $(eval $(call copy-one-file,$(LOCAL_FULL_MANIFEST_FILE),$(my_static_library_android_manifest)))
+  $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_android_manifest))
 endif # LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
 
 ifneq ($(TURBINE_ENABLED),false)
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
index b34e5b6..abb46ac 100644
--- a/target/product/sdk_phone_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -20,6 +20,10 @@
 -include sdk/build/product_sdk.mk
 -include development/build/product_sdk.mk
 
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+    EmulatorSmokeTests
+
 # Overrides
 PRODUCT_BRAND := Android
 PRODUCT_NAME := sdk_phone_x86
diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk
index 37c078e..828b744 100644
--- a/target/product/sdk_phone_x86_64.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -20,6 +20,10 @@
 -include sdk/build/product_sdk.mk
 -include development/build/product_sdk.mk
 
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+    EmulatorSmokeTests
+
 # Overrides
 PRODUCT_BRAND := Android
 PRODUCT_NAME := sdk_phone_x86_64
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 756bc8a..393c33d 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -27,6 +27,12 @@
       in the apkcerts.txt file.  Option may be repeated to give
       multiple extra packages.
 
+  --skip_apks_with_path_prefix  <prefix>
+      Skip signing an APK if it has the matching prefix in its path. The prefix
+      should be matching the entry name, which has partition names in upper
+      case, e.g. "VENDOR/app/", or "SYSTEM_OTHER/preloads/". Option may be
+      repeated to give multiple prefixes.
+
   -k  (--key_mapping)  <src_key=dest_key>
       Add a mapping from the key name as specified in apkcerts.txt (the
       src_key) to the real key you wish to sign the package with
@@ -118,6 +124,7 @@
 OPTIONS = common.OPTIONS
 
 OPTIONS.extra_apks = {}
+OPTIONS.skip_apks_with_path_prefix = set()
 OPTIONS.key_map = {}
 OPTIONS.rebuild_recovery = False
 OPTIONS.replace_ota_keys = False
@@ -144,39 +151,53 @@
   return certmap
 
 
-def GetApkFileInfo(filename, compressed_extension):
+def GetApkFileInfo(filename, compressed_extension, skipped_prefixes):
   """Returns the APK info based on the given filename.
 
   Checks if the given filename (with path) looks like an APK file, by taking the
-  compressed extension into consideration.
+  compressed extension into consideration. If it appears to be an APK file,
+  further checks if the APK file should be skipped when signing, based on the
+  given path prefixes.
 
   Args:
     filename: Path to the file.
     compressed_extension: The extension string of compressed APKs (e.g. ".gz"),
         or None if there's no compressed APKs.
+    skipped_prefixes: A set/list/tuple of the path prefixes to be skipped.
 
   Returns:
-    (is_apk, is_compressed): is_apk indicates whether the given filename is an
-    APK file. is_compressed indicates whether the APK file is compressed (only
-    meaningful when is_apk is True).
+    (is_apk, is_compressed, should_be_skipped): is_apk indicates whether the
+    given filename is an APK file. is_compressed indicates whether the APK file
+    is compressed (only meaningful when is_apk is True). should_be_skipped
+    indicates whether the filename matches any of the given prefixes to be
+    skipped.
 
   Raises:
-    AssertionError: On invalid compressed_extension input.
+    AssertionError: On invalid compressed_extension or skipped_prefixes inputs.
   """
   assert compressed_extension is None or compressed_extension.startswith('.'), \
       "Invalid compressed_extension arg: '{}'".format(compressed_extension)
 
+  # skipped_prefixes should be one of set/list/tuple types. Other types such as
+  # str shouldn't be accepted.
+  assert (isinstance(skipped_prefixes, tuple) or
+          isinstance(skipped_prefixes, set) or
+          isinstance(skipped_prefixes, list)), \
+              "Invalid skipped_prefixes input type: {}".format(
+                  type(skipped_prefixes))
+
   compressed_apk_extension = (
       ".apk" + compressed_extension if compressed_extension else None)
   is_apk = (filename.endswith(".apk") or
             (compressed_apk_extension and
              filename.endswith(compressed_apk_extension)))
   if not is_apk:
-    return (False, False)
+    return (False, False, False)
 
   is_compressed = (compressed_apk_extension and
                    filename.endswith(compressed_apk_extension))
-  return (True, is_compressed)
+  should_be_skipped = filename.startswith(tuple(skipped_prefixes))
+  return (True, is_compressed, should_be_skipped)
 
 
 def CheckAllApksSigned(input_tf_zip, apk_key_map, compressed_extension):
@@ -193,9 +214,9 @@
   """
   unknown_apks = []
   for info in input_tf_zip.infolist():
-    (is_apk, is_compressed) = GetApkFileInfo(
-        info.filename, compressed_extension)
-    if not is_apk:
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        info.filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+    if not is_apk or should_be_skipped:
       continue
     name = os.path.basename(info.filename)
     if is_compressed:
@@ -276,9 +297,11 @@
                        apk_key_map, key_passwords, platform_api_level,
                        codename_to_api_level_map,
                        compressed_extension):
+  # maxsize measures the maximum filename length, including the ones to be
+  # skipped.
   maxsize = max(
       [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
-       if GetApkFileInfo(i.filename, compressed_extension)[0]])
+       if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
   system_root_image = misc_info.get("system_root_image") == "true"
 
   for info in input_tf_zip.infolist():
@@ -288,10 +311,18 @@
 
     data = input_tf_zip.read(filename)
     out_info = copy.copy(info)
-    (is_apk, is_compressed) = GetApkFileInfo(filename, compressed_extension)
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+
+    if is_apk and should_be_skipped:
+      # Copy skipped APKs verbatim.
+      print(
+          "NOT signing: %s\n"
+          "        (skipped due to matching prefix)" % (filename,))
+      common.ZipWriteStr(output_tf_zip, out_info, data)
 
     # Sign APKs.
-    if is_apk:
+    elif is_apk:
       name = os.path.basename(filename)
       if is_compressed:
         name = name[:-len(compressed_extension)]
@@ -304,7 +335,9 @@
         common.ZipWriteStr(output_tf_zip, out_info, signed_data)
       else:
         # an APK we're not supposed to sign.
-        print("NOT signing: %s" % (name,))
+        print(
+            "NOT signing: %s\n"
+            "        (skipped due to special cert string)" % (name,))
         common.ZipWriteStr(output_tf_zip, out_info, data)
 
     # System properties.
@@ -794,6 +827,12 @@
       names = names.split(",")
       for n in names:
         OPTIONS.extra_apks[n] = key
+    elif o == "--skip_apks_with_path_prefix":
+      # Sanity check the prefix, which must be in all upper case.
+      prefix = a.split('/')[0]
+      if not prefix or prefix != prefix.upper():
+        raise ValueError("Invalid path prefix '%s'" % (a,))
+      OPTIONS.skip_apks_with_path_prefix.add(a)
     elif o in ("-d", "--default_key_mappings"):
       key_mapping_options.append((None, a))
     elif o in ("-k", "--key_mapping"):
@@ -853,6 +892,7 @@
       extra_opts="e:d:k:ot:",
       extra_long_opts=[
           "extra_apks=",
+          "skip_apks_with_path_prefix=",
           "default_key_mappings=",
           "key_mapping=",
           "replace_ota_keys",
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 71bd259..ac1b567 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -237,25 +237,116 @@
           AssertionError, CheckAllApksSigned, input_zip, apk_key_map, '.gz')
 
   def test_GetApkFileInfo(self):
-    (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk", None)
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk", None, [])
     self.assertTrue(is_apk)
     self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
 
-    (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.dat", None)
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk", None, [])
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.dat", None, [])
     self.assertFalse(is_apk)
     self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
 
   def test_GetApkFileInfo_withCompressedApks(self):
-    (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk.gz", ".gz")
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk.gz", ".gz", [])
     self.assertTrue(is_apk)
     self.assertTrue(is_compressed)
+    self.assertFalse(should_be_skipped)
 
-    (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk.gz", ".xz")
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/apps/Chats.apk.gz", ".xz", [])
     self.assertFalse(is_apk)
     self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
 
     self.assertRaises(
-        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "")
+        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "", [])
 
     self.assertRaises(
-        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk")
+        AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk", [])
+
+  def test_GetApkFileInfo_withSkippedPrefixes(self):
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/preloads/apps/Chats.apk", None, set())
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "PRODUCT/preloads/apps/Chats.apk",
+        None,
+        set(["PRODUCT/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        set(["SYSTEM/preloads/", "SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk.gz",
+        ".gz",
+        set(["PRODUCT/prebuilts/", "SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertTrue(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.dat",
+        None,
+        set(["SYSTEM_OTHER/preloads/"]))
+    self.assertFalse(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertFalse(should_be_skipped)
+
+  def test_GetApkFileInfo_checkSkippedPrefixesInput(self):
+    # set
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        set(["SYSTEM_OTHER/preloads/"]))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # tuple
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        ("SYSTEM_OTHER/preloads/",))
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # list
+    (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+        "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None,
+        ["SYSTEM_OTHER/preloads/"])
+    self.assertTrue(is_apk)
+    self.assertFalse(is_compressed)
+    self.assertTrue(should_be_skipped)
+
+    # str is invalid.
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None, "SYSTEM_OTHER/preloads/")
+
+    # None is invalid.
+    self.assertRaises(
+        AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+        None, None)