Updating Security String to 2017-01-05 on nyc-dev am: 190129bc61
am: b9085822a5

Change-Id: I8230fa0c0c13b89274bab56a04b183e4c8b0ebe7
diff --git a/core/Makefile b/core/Makefile
index 2031132..5badde5 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1383,6 +1383,8 @@
 $(INSTALLED_USERDATATARBALL_TARGET): $(FS_GET_STATS) $(INTERNAL_USERDATAIMAGE_FILES)
 	$(build-userdatatarball-target)
 
+$(call dist-for-goals,userdatatarball,$(INSTALLED_USERDATATARBALL_TARGET))
+
 .PHONY: userdatatarball-nodeps
 userdatatarball-nodeps: $(FS_GET_STATS)
 	$(build-userdatatarball-target)
@@ -2039,7 +2041,7 @@
 # the dependency will be set up later in build/core/main.mk.
 $(PROGUARD_DICT_ZIP) :
 	@echo "Packaging Proguard obfuscation dictionary files."
-	$(hide) dict_files=`find $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS -name proguard_dictionary`; \
+	$(hide) dict_files=`find $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS -name proguard_dictionary -o -name jack_dictionary`; \
 		if [ -n "$$dict_files" ]; then \
 		  unobfuscated_jars=$${dict_files//proguard_dictionary/classes.jar}; \
 		  zip -qX $@ $$dict_files $$unobfuscated_jars; \
diff --git a/core/pathmap.mk b/core/pathmap.mk
index edc584b..effc878 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -121,6 +121,7 @@
         design \
         percent \
         recommendation \
+        transition \
         v7/preference \
         v14/preference \
         v17/preference-leanback \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index e0db15d..550fc70 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -43,7 +43,7 @@
   # which is the version that we reveal to the end user.
   # Update this value when the platform version changes (rather
   # than overriding it somewhere else).  Can be an arbitrary string.
-  PLATFORM_VERSION := 7.1
+  PLATFORM_VERSION := 7.1.1
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 325b0ce..02c1c88 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -45,28 +45,6 @@
 # the GLES renderer disables itself if host GL acceleration isn't available.
 USE_OPENGL_RENDERER := true
 
-# Set the phase offset of the system's vsync event relative to the hardware
-# vsync. The system's vsync event drives Choreographer and SurfaceFlinger's
-# rendering. This value is the number of nanoseconds after the hardware vsync
-# that the system vsync event will occur.
-#
-# This phase offset allows adjustment of the minimum latency from application
-# wake-up (by Choregographer) time to the time at which the resulting window
-# image is displayed.  This value may be either positive (after the HW vsync)
-# or negative (before the HW vsync).  Setting it to 0 will result in a
-# minimum latency of two vsync periods because the app and SurfaceFlinger
-# will run just after the HW vsync.  Setting it to a positive number will
-# result in the minimum latency being:
-#
-#     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
-#
-# Note that reducing this latency makes it more likely for the applications
-# to not have their window content image ready in time.  When this happens
-# the latency will end up being an additional vsync period, and animations
-# will hiccup.  Therefore, this latency should be tuned somewhat
-# conservatively (or at least with awareness of the trade-off being made).
-VSYNC_EVENT_PHASE_OFFSET_NS := 0
-
 TARGET_USERIMAGES_USE_EXT4 := true
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1879048192  # 1.75 GB
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
diff --git a/target/board/generic/sepolicy/file_contexts b/target/board/generic/sepolicy/file_contexts
index e8d32f7..e9502d9 100644
--- a/target/board/generic/sepolicy/file_contexts
+++ b/target/board/generic/sepolicy/file_contexts
@@ -9,6 +9,7 @@
 /dev/block/vdc               u:object_r:userdata_block_device:s0
 
 /dev/goldfish_pipe           u:object_r:qemu_device:s0
+/dev/goldfish_sync           u:object_r:qemu_device:s0
 /dev/qemu_.*                 u:object_r:qemu_device:s0
 /dev/socket/qemud            u:object_r:qemud_socket:s0
 /dev/ttyGF[0-9]*             u:object_r:serial_device:s0
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 553bec9..283e9cc 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -38,7 +38,7 @@
 USE_OPENGL_RENDERER := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1879048192  # 1.75 GB
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2147483648 # 2 GB
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 0d9aabd..31dabc7 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -696,10 +696,19 @@
     with open(prefix + ".new.dat", "wb") as new_f:
       for xf in self.transfers:
         if xf.style == "zero":
-          pass
+          tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
+          print("%10d %10d (%6.2f%%) %7s %s %s" % (
+              tgt_size, tgt_size, 100.0, xf.style, xf.tgt_name,
+              str(xf.tgt_ranges)))
+
         elif xf.style == "new":
           for piece in self.tgt.ReadRangeSet(xf.tgt_ranges):
             new_f.write(piece)
+          tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
+          print("%10d %10d (%6.2f%%) %7s %s %s" % (
+              tgt_size, tgt_size, 100.0, xf.style,
+              xf.tgt_name, str(xf.tgt_ranges)))
+
         elif xf.style == "diff":
           src = self.src.ReadRangeSet(xf.src_ranges)
           tgt = self.tgt.ReadRangeSet(xf.tgt_ranges)
@@ -726,6 +735,12 @@
             # These are identical; we don't need to generate a patch,
             # just issue copy commands on the device.
             xf.style = "move"
+            if xf.src_ranges != xf.tgt_ranges:
+              print("%10d %10d (%6.2f%%) %7s %s %s (from %s)" % (
+                  tgt_size, tgt_size, 100.0, xf.style,
+                  xf.tgt_name if xf.tgt_name == xf.src_name else (
+                      xf.tgt_name + " (from " + xf.src_name + ")"),
+                  str(xf.tgt_ranges), str(xf.src_ranges)))
           else:
             # For files in zip format (eg, APKs, JARs, etc.) we would
             # like to use imgdiff -z if possible (because it usually
@@ -773,10 +788,11 @@
           size = len(patch)
           with lock:
             patches[patchnum] = (patch, xf)
-            print("%10d %10d (%6.2f%%) %7s %s" % (
+            print("%10d %10d (%6.2f%%) %7s %s %s %s" % (
                 size, tgt_size, size * 100.0 / tgt_size, xf.style,
                 xf.tgt_name if xf.tgt_name == xf.src_name else (
-                    xf.tgt_name + " (from " + xf.src_name + ")")))
+                    xf.tgt_name + " (from " + xf.src_name + ")"),
+                str(xf.tgt_ranges), str(xf.src_ranges)))
 
       threads = [threading.Thread(target=diff_worker)
                  for _ in range(self.threads)]
@@ -1102,27 +1118,23 @@
   def FindTransfers(self):
     """Parse the file_map to generate all the transfers."""
 
-    def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
-                    split=False):
-      """Wrapper function for adding a Transfer().
+    def AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges,
+                          style, by_id):
+      """Add one or multiple Transfer()s by splitting large files.
 
       For BBOTA v3, we need to stash source blocks for resumable feature.
       However, with the growth of file size and the shrink of the cache
       partition source blocks are too large to be stashed. If a file occupies
-      too many blocks (greater than MAX_BLOCKS_PER_DIFF_TRANSFER), we split it
-      into smaller pieces by getting multiple Transfer()s.
+      too many blocks, we split it into smaller pieces by getting multiple
+      Transfer()s.
 
       The downside is that after splitting, we may increase the package size
       since the split pieces don't align well. According to our experiments,
       1/8 of the cache size as the per-piece limit appears to be optimal.
       Compared to the fixed 1024-block limit, it reduces the overall package
-      size by 30% volantis, and 20% for angler and bullhead."""
+      size by 30% for volantis, and 20% for angler and bullhead."""
 
-      # We care about diff transfers only.
-      if style != "diff" or not split:
-        Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
-        return
-
+      # Possibly split large files into smaller chunks.
       pieces = 0
       cache_size = common.OPTIONS.cache_size
       split_threshold = 0.125
@@ -1158,6 +1170,74 @@
         Transfer(tgt_split_name, src_split_name, tgt_ranges, src_ranges, style,
                  by_id)
 
+    def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
+                    split=False):
+      """Wrapper function for adding a Transfer()."""
+
+      # We specialize diff transfers only (which covers bsdiff/imgdiff/move);
+      # otherwise add the Transfer() as is.
+      if style != "diff" or not split:
+        Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+        return
+
+      # Handle .odex files specially to analyze the block-wise difference. If
+      # most of the blocks are identical with only few changes (e.g. header),
+      # we will patch the changed blocks only. This avoids stashing unchanged
+      # blocks while patching. We limit the analysis to files without size
+      # changes only. This is to avoid sacrificing the OTA generation cost too
+      # much.
+      if (tgt_name.split(".")[-1].lower() == 'odex' and
+          tgt_ranges.size() == src_ranges.size()):
+
+        # 0.5 threshold can be further tuned. The tradeoff is: if only very
+        # few blocks remain identical, we lose the opportunity to use imgdiff
+        # that may have better compression ratio than bsdiff.
+        crop_threshold = 0.5
+
+        tgt_skipped = RangeSet()
+        src_skipped = RangeSet()
+        tgt_size = tgt_ranges.size()
+        tgt_changed = 0
+        for src_block, tgt_block in zip(src_ranges.next_item(),
+                                        tgt_ranges.next_item()):
+          src_rs = RangeSet(str(src_block))
+          tgt_rs = RangeSet(str(tgt_block))
+          if self.src.ReadRangeSet(src_rs) == self.tgt.ReadRangeSet(tgt_rs):
+            tgt_skipped = tgt_skipped.union(tgt_rs)
+            src_skipped = src_skipped.union(src_rs)
+          else:
+            tgt_changed += tgt_rs.size()
+
+          # Terminate early if no clear sign of benefits.
+          if tgt_changed > tgt_size * crop_threshold:
+            break
+
+        if tgt_changed < tgt_size * crop_threshold:
+          assert tgt_changed + tgt_skipped.size() == tgt_size
+          print('%10d %10d (%6.2f%%) %s' % (tgt_skipped.size(), tgt_size,
+                tgt_skipped.size() * 100.0 / tgt_size, tgt_name))
+          AddSplitTransfers(
+              "%s-skipped" % (tgt_name,),
+              "%s-skipped" % (src_name,),
+              tgt_skipped, src_skipped, style, by_id)
+
+          # Intentionally change the file extension to avoid being imgdiff'd as
+          # the files are no longer in their original format.
+          tgt_name = "%s-cropped" % (tgt_name,)
+          src_name = "%s-cropped" % (src_name,)
+          tgt_ranges = tgt_ranges.subtract(tgt_skipped)
+          src_ranges = src_ranges.subtract(src_skipped)
+
+          # Possibly having no changed blocks.
+          if not tgt_ranges:
+            return
+
+      # Add the transfer(s).
+      AddSplitTransfers(
+          tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+
+    print("Finding transfers...")
+
     empty = RangeSet()
     for tgt_fn, tgt_ranges in self.tgt.file_map.items():
       if tgt_fn == "__ZERO":
diff --git a/tools/releasetools/rangelib.py b/tools/releasetools/rangelib.py
index aa572cc..c9bd375 100644
--- a/tools/releasetools/rangelib.py
+++ b/tools/releasetools/rangelib.py
@@ -300,6 +300,20 @@
         n -= e - s
     return RangeSet(data=out)
 
+  def next_item(self):
+    """Return the next integer represented by the RangeSet.
+
+    >>> list(RangeSet("0-9").next_item())
+    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    >>> list(RangeSet("10-19 3-5").next_item())
+    [3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
+    >>> list(rangelib.RangeSet("10-19 3 5 7").next_item())
+    [3, 5, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
+    """
+    for s, e in self:
+      for element in range(s, e):
+        yield element
+
 
 if __name__ == "__main__":
   import doctest
diff --git a/tools/releasetools/test_rangelib.py b/tools/releasetools/test_rangelib.py
index a61a64e..edf1c4b 100644
--- a/tools/releasetools/test_rangelib.py
+++ b/tools/releasetools/test_rangelib.py
@@ -124,3 +124,14 @@
     self.assertTrue(RangeSet(data=[2, 9, 30, 31, 31, 32, 35, 36]).monotonic)
     self.assertTrue(RangeSet(data=[0, 5, 5, 10]).monotonic)
     self.assertFalse(RangeSet(data=[5, 10, 0, 5]).monotonic)
+
+  def test_next_item(self):
+    self.assertEqual(
+        list(RangeSet("0-9").next_item()),
+        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    self.assertEqual(
+        list(RangeSet("10-19 3-5").next_item()),
+        [3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
+    self.assertEqual(
+        list(RangeSet("10-19 3 5 7").next_item()),
+        [3, 5, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])