Merge "Add local preopt options for generating app image and profile"
diff --git a/core/definitions.mk b/core/definitions.mk
index 56176ca..a179df4 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -3243,6 +3243,14 @@
 #$(warning 42 == $(call math_max,5,42))
 #$(warning 42 == $(call math_max,42,5))
 
+define math_gt_or_eq
+$(if $(filter $(1),$(call math_max,$(1),$(2))),true)
+endef
+
+#$(warning $(call math_gt_or_eq, 2, 1))
+#$(warning $(call math_gt_or_eq, 1, 1))
+#$(warning $(if $(call math_gt_or_eq, 1, 2),false,true))
+
 # $1 is the variable name to increment
 define inc_and_print
 $(strip $(eval $(1) := $($(1)) .)$(words $($(1))))
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 41c4b2e..ffb888c 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -119,7 +119,7 @@
 	--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
 	--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
 	--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
-	--include-patch-information --runtime-arg -Xnorelocate --compile-pic \
+	--runtime-arg -Xnorelocate --compile-pic \
 	--no-generate-debug-info --generate-build-id \
 	--abort-on-hard-verifier-error \
 	--no-inline-from=core-oj.jar \
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 54211a4..860a66a 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -72,7 +72,7 @@
 		--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
 		--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
 		--android-root=$(PRODUCT_OUT)/system \
-		--include-patch-information --runtime-arg -Xnorelocate --compile-pic \
+		--runtime-arg -Xnorelocate --compile-pic \
 		--no-generate-debug-info --generate-build-id \
 		--multi-image --no-inline-from=core-oj.jar \
 		$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(GLOBAL_DEXPREOPT_FLAGS) $(COMPILED_CLASSES_FLAGS) $(ART_BOOT_IMAGE_EXTRA_ARGS)
diff --git a/core/main.mk b/core/main.mk
index 739fc11..7433f90 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -343,6 +343,16 @@
   ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
 endif
 
+# Boolean variable determining if Treble is fully enabled
+PRODUCT_FULL_TREBLE := false
+ifeq ($(PRODUCT_FULL_TREBLE_OVERRIDE),true)
+  PRODUCT_FULL_TREBLE := true
+else ifeq ($(PRODUCT_SHIPPING_API_LEVEL),)
+  #$(warning no product shipping level defined)
+else ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),26),)
+  PRODUCT_FULL_TREBLE := true
+endif
+
 # -----------------------------------------------------------------
 ###
 ### In this section we set up the things that are different
diff --git a/envsetup.sh b/envsetup.sh
index b239441..9680780 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1148,8 +1148,7 @@
             adb shell cat $TMP
         else
             # Dump stacks of native process
-            local USE64BIT="$(is64bit $PID)"
-            adb shell debuggerd$USE64BIT -b $PID
+            adb shell debuggerd -b $PID
         fi
     fi
 }
diff --git a/target/product/core.mk b/target/product/core.mk
index 10b2c9e..c4c7cab 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -25,6 +25,7 @@
     BlockedNumberProvider \
     BookmarkProvider \
     Browser2 \
+    BuiltInPrintService \
     Calendar \
     CalendarProvider \
     CaptivePortalLogin \
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 17a318f..8b40fe0 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -120,4 +120,4 @@
 
 # Framework Manifest
 PRODUCT_COPY_FILES += \
-    system/libhidl/sintf.xml:system/manifest.xml
+    system/libhidl/manifest.xml:system/manifest.xml
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 0f42c27..fb52d67 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -80,4 +80,5 @@
     ro.dalvik.vm.native.bridge=0 \
     dalvik.vm.usejit=true \
     dalvik.vm.usejitprofiles=true \
+    dalvik.vm.dexopt.secondary=true \
     dalvik.vm.appimageformat=lz4
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 28fd474..9403a77 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -77,11 +77,10 @@
   """Generate care_map of system (or vendor) partition"""
 
   assert which in ("system", "vendor")
-  _, blk_device = common.GetTypeAndDevice("/" + which, OPTIONS.info_dict)
 
   simg = sparse_img.SparseImage(imgname)
   care_map_list = []
-  care_map_list.append(blk_device)
+  care_map_list.append(which)
 
   care_map_ranges = simg.care_map
   key = which + "_adjusted_partition_size"
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 956f000..b57c1b5 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -153,9 +153,7 @@
     raise ValueError("can't find META/misc_info.txt in input target-files")
 
   assert "recovery_api_version" in d
-
-  if "fstab_version" not in d:
-    d["fstab_version"] = "1"
+  assert "fstab_version" in d
 
   # A few properties are stored as links to the files in the out/ directory.
   # It works fine with the build system. However, they are no longer available
@@ -251,6 +249,7 @@
   d["build.prop"] = LoadBuildProp(read_helper)
   return d
 
+
 def LoadBuildProp(read_helper):
   try:
     data = read_helper("SYSTEM/build.prop")
@@ -259,6 +258,7 @@
     data = ""
   return LoadDictionaryFromLines(data.split("\n"))
 
+
 def LoadDictionaryFromLines(lines):
   d = {}
   for line in lines:
@@ -270,15 +270,15 @@
       d[name] = value
   return d
 
+
 def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
                       system_root_image=False):
   class Partition(object):
-    def __init__(self, mount_point, fs_type, device, length, device2, context):
+    def __init__(self, mount_point, fs_type, device, length, context):
       self.mount_point = mount_point
       self.fs_type = fs_type
       self.device = device
       self.length = length
-      self.device2 = device2
       self.context = context
 
   try:
@@ -287,81 +287,44 @@
     print("Warning: could not find {}".format(recovery_fstab_path))
     data = ""
 
-  if fstab_version == 1:
-    d = {}
-    for line in data.split("\n"):
-      line = line.strip()
-      if not line or line.startswith("#"):
-        continue
-      pieces = line.split()
-      if not 3 <= len(pieces) <= 4:
-        raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
-      options = None
-      if len(pieces) >= 4:
-        if pieces[3].startswith("/"):
-          device2 = pieces[3]
-          if len(pieces) >= 5:
-            options = pieces[4]
-        else:
-          device2 = None
-          options = pieces[3]
+  assert fstab_version == 2
+
+  d = {}
+  for line in data.split("\n"):
+    line = line.strip()
+    if not line or line.startswith("#"):
+      continue
+
+    # <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+    pieces = line.split()
+    if len(pieces) != 5:
+      raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
+
+    # Ignore entries that are managed by vold.
+    options = pieces[4]
+    if "voldmanaged=" in options:
+      continue
+
+    # It's a good line, parse it.
+    length = 0
+    options = options.split(",")
+    for i in options:
+      if i.startswith("length="):
+        length = int(i[7:])
       else:
-        device2 = None
-
-      mount_point = pieces[0]
-      length = 0
-      if options:
-        options = options.split(",")
-        for i in options:
-          if i.startswith("length="):
-            length = int(i[7:])
-          else:
-            print("%s: unknown option \"%s\"" % (mount_point, i))
-
-      d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[1],
-                                 device=pieces[2], length=length,
-                                 device2=device2)
-
-  elif fstab_version == 2:
-    d = {}
-    for line in data.split("\n"):
-      line = line.strip()
-      if not line or line.startswith("#"):
-        continue
-      # <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
-      pieces = line.split()
-      if len(pieces) != 5:
-        raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
-
-      # Ignore entries that are managed by vold
-      options = pieces[4]
-      if "voldmanaged=" in options:
+        # Ignore all unknown options in the unified fstab.
         continue
 
-      # It's a good line, parse it
-      length = 0
-      options = options.split(",")
-      for i in options:
-        if i.startswith("length="):
-          length = int(i[7:])
-        else:
-          # Ignore all unknown options in the unified fstab
-          continue
+    mount_flags = pieces[3]
+    # Honor the SELinux context if present.
+    context = None
+    for i in mount_flags.split(","):
+      if i.startswith("context="):
+        context = i
 
-      mount_flags = pieces[3]
-      # Honor the SELinux context if present.
-      context = None
-      for i in mount_flags.split(","):
-        if i.startswith("context="):
-          context = i
-
-      mount_point = pieces[1]
-      d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[2],
-                                 device=pieces[0], length=length,
-                                 device2=None, context=context)
-
-  else:
-    raise ValueError("Unknown fstab_version: \"%d\"" % (fstab_version,))
+    mount_point = pieces[1]
+    d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[2],
+                               device=pieces[0], length=length, context=context)
 
   # / is used for the system mount point when the root directory is included in
   # system. Other areas assume system is always at "/system" so point /system
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 4b1b3a0..be01a6d 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -72,7 +72,19 @@
       will be replaced by "ota-downgrade=yes" in the metadata file. A data
       wipe will always be enforced, so "ota-wipe=yes" will also be included in
       the metadata file. The update-binary in the source build will be used in
-      the OTA package, unless --binary flag is specified.
+      the OTA package, unless --binary flag is specified. Please also check the
+      doc for --override_timestamp below.
+
+  --override_timestamp
+      Intentionally generate an incremental OTA that updates from a newer
+      build to an older one (based on timestamp comparison), by overriding the
+      timestamp in package metadata. This differs from --downgrade flag: we
+      know for sure this is NOT an actual downgrade case, but two builds are
+      cut in a reverse order. A legit use case is that we cut a new build C
+      (after having A and B), but want to enfore an update path of A -> C -> B.
+      Specifying --downgrade may not help since that would enforce a data wipe
+      for C -> B update. The value of "post-timestamp" will be set to the newer
+      timestamp plus one, so that the package can be pushed and applied.
 
   -e  (--extra_script)  <file>
       Insert the contents of file at the end of the update script.
@@ -149,6 +161,7 @@
 OPTIONS.patch_threshold = 0.95
 OPTIONS.wipe_user_data = False
 OPTIONS.downgrade = False
+OPTIONS.timestamp = False
 OPTIONS.extra_script = None
 OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
 if OPTIONS.worker_threads == 0:
@@ -840,20 +853,21 @@
   is_downgrade = long(post_timestamp) < long(pre_timestamp)
 
   if OPTIONS.downgrade:
-    metadata["ota-downgrade"] = "yes"
     if not is_downgrade:
       raise RuntimeError("--downgrade specified but no downgrade detected: "
                          "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+    metadata["ota-downgrade"] = "yes"
+  elif OPTIONS.timestamp:
+    if not is_downgrade:
+      raise RuntimeError("--timestamp specified but no timestamp hack needed: "
+                         "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+    metadata["post-timestamp"] = str(long(pre_timestamp) + 1)
   else:
     if is_downgrade:
-      # Non-fatal here to allow generating such a package which may require
-      # manual work to adjust the post-timestamp. A legit use case is that we
-      # cut a new build C (after having A and B), but want to enfore the
-      # update path of A -> C -> B. Specifying --downgrade may not help since
-      # that would enforce a data wipe for C -> B update.
-      print("\nWARNING: downgrade detected: pre: %s, post: %s.\n"
-            "The package may not be deployed properly. "
-            "Try --downgrade?\n" % (pre_timestamp, post_timestamp))
+      raise RuntimeError("Downgrade detected based on timestamp check: "
+                         "pre: %s, post: %s. Need to specify --timestamp OR "
+                         "--downgrade to allow building the incremental." % (
+                             pre_timestamp, post_timestamp))
     metadata["post-timestamp"] = post_timestamp
 
 
@@ -2075,6 +2089,8 @@
     elif o == "--downgrade":
       OPTIONS.downgrade = True
       OPTIONS.wipe_user_data = True
+    elif o == "--override_timestamp":
+      OPTIONS.timestamp = True
     elif o in ("-o", "--oem_settings"):
       OPTIONS.oem_source = a.split(',')
     elif o == "--oem_no_mount":
@@ -2127,6 +2143,7 @@
                                  "full_bootloader",
                                  "wipe_user_data",
                                  "downgrade",
+                                 "override_timestamp",
                                  "extra_script=",
                                  "worker_threads=",
                                  "two_step",
@@ -2159,6 +2176,9 @@
     if OPTIONS.incremental_source is None:
       raise ValueError("Cannot generate downgradable full OTAs")
 
+  assert not (OPTIONS.downgrade and OPTIONS.timestamp), \
+      "Cannot have --downgrade AND --override_timestamp both"
+
   # Load the dict file from the zip directly to have a peek at the OTA type.
   # For packages using A/B update, unzipping is not needed.
   input_zip = zipfile.ZipFile(args[0], "r")