Merge "Offer an ApkSignerEngine implementation."
diff --git a/core/Makefile b/core/Makefile
index 6fb2458..83a008c 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1678,11 +1678,12 @@
 
 ifeq ($(AB_OTA_UPDATER),true)
 # Build zlib fingerprint if using the AB Updater.
-$(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
+updater_dep := $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
 else
 # Build OTA tools if not using the AB Updater.
-$(BUILT_TARGET_FILES_PACKAGE): $(built_ota_tools)
+updater_dep := $(built_ota_tools)
 endif
+$(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
 
 # If we are using recovery as boot, output recovery files to BOOT/.
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -1705,6 +1706,7 @@
 		$(SELINUX_FC) \
 		$(APKCERTS_FILE) \
 		$(HOST_OUT_EXECUTABLES)/fs_config \
+		build/tools/releasetools/add_img_to_target_files \
 		| $(ACP)
 	@echo "Package target files: $@"
 	$(hide) rm -rf $@ $(zip_root)
@@ -1873,6 +1875,17 @@
 	@# Include the build type in META/misc_info.txt so the server can easily differentiate production builds.
 	$(hide) echo "build_type=$(TARGET_BUILD_VARIANT)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "ab_update=true" >> $(zip_root)/META/misc_info.txt
+ifdef BRILLO_VENDOR_PARTITIONS
+	$(hide) mkdir -p $(zip_root)/VENDOR_IMAGES
+	$(hide) for f in $(BRILLO_VENDOR_PARTITIONS); do \
+	  pair1="$$(echo $$f | awk -F':' '{print $$1}')"; \
+	  pair2="$$(echo $$f | awk -F':' '{print $$2}')"; \
+	  src=$${pair1}/$${pair2}; \
+	  dest=$(zip_root)/VENDOR_IMAGES/$${pair2}; \
+	  mkdir -p $$(dirname "$${dest}"); \
+	  $(ACP) $${src} $${dest}; \
+	done;
+endif
 ifdef OSRELEASED_DIRECTORY
 	$(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_id $(zip_root)/META/product_id.txt
 	$(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_version $(zip_root)/META/product_version.txt
@@ -1923,7 +1936,8 @@
 
 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
 
-$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
+		build/tools/releasetools/ota_from_target_files
 	@echo "Package OTA: $@"
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/ota_from_target_files -v \
@@ -1949,7 +1963,8 @@
 
 INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
 
-$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
+		build/tools/releasetools/img_from_target_files
 	@echo "Package: $@"
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/img_from_target_files -v \
@@ -1972,7 +1987,11 @@
 SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
 # For apps_only build we'll establish the dependency later in build/core/main.mk.
 ifndef TARGET_BUILD_APPS
-$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
+$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_BOOTIMAGE_TARGET) \
+		$(INSTALLED_USERDATAIMAGE_TARGET) \
+		$(INSTALLED_VENDORIMAGE_TARGET) \
+		$(updater_dep)
 endif
 $(SYMBOLS_ZIP):
 	@echo "Package symbols: $@"
diff --git a/core/clang/tidy.mk b/core/clang/tidy.mk
index e61b878..019e6f0 100644
--- a/core/clang/tidy.mk
+++ b/core/clang/tidy.mk
@@ -15,22 +15,25 @@
 #
 
 # Most Android source files are not clang-tidy clean yet.
-# Global tidy checks include only google* minus google-readability*.
+# Global tidy checks include only google* and misc-macro-parentheses,
+# but not google-readability*.
 DEFAULT_GLOBAL_TIDY_CHECKS := \
-  -*,google*,-google-readability*
+  -*,google*,-google-readability*,misc-macro-parentheses
 
-# Disable google style rules usually not followed by external projects.
+# Disable style rules usually not followed by external projects.
 # Every word in DEFAULT_LOCAL_TIDY_CHECKS list has the following format:
 #   <local_path_prefix>:,<tidy-check-pattern>
 # The tidy-check-patterns of all matching local_path_prefixes will be used.
 # For example, external/google* projects will have:
 #   ,-google-build-using-namespace,-google-explicit-constructor
-#   ,-google-runtime-int,google-runtime-int
-# where google-runtime-int is enabled at the end.
+#   ,-google-runtime-int,-misc-macro-parentheses,
+#   ,google-runtime-int,misc-macro-parentheses
+# where google-runtime-int and misc-macro-parentheses are enabled at the end.
 DEFAULT_LOCAL_TIDY_CHECKS := \
   external/:,-google-build-using-namespace \
   external/:,-google-explicit-constructor,-google-runtime-int \
-  external/google:,google-runtime-int \
+  external/:,-misc-macro-parentheses \
+  external/google:,google-runtime-int,misc-macro-parentheses \
   external/webrtc/:,google-runtime-int \
   hardware/qcom:,-google-build-using-namespace \
   hardware/qcom:,-google-explicit-constructor,-google-runtime-int \
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index 5d5b050..5517a79 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -31,6 +31,11 @@
 	arch_variant_ldflags := \
 		-Wl,--no-fix-cortex-a8
 else
+ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)),cortex-a9)
+	arch_variant_cflags := -march=armv7-a
+	arch_variant_ldflags := \
+		-Wl,--no-fix-cortex-a8
+else
 	arch_variant_cflags := -march=armv7-a
 	# Generic ARM might be a Cortex A8 -- better safe than sorry
 	arch_variant_ldflags := \
@@ -38,6 +43,7 @@
 endif
 endif
 endif
+endif
 
 ifeq (true,$(local_arch_has_lpae))
 	# Fake an ARM compiler flag as these processors support LPAE which GCC/clang
diff --git a/core/combo/arch/x86/x86_64.mk b/core/combo/arch/x86/x86_64.mk
new file mode 100644
index 0000000..620fbd8
--- /dev/null
+++ b/core/combo/arch/x86/x86_64.mk
@@ -0,0 +1,18 @@
+# This file is used as the second (32-bit) architecture when building a generic
+# x86_64 64-bit platform image. (full_x86_64-eng / sdk_x86_64-eng)
+#
+# The generic 'x86' variant cannot be used, since it resets some flags used
+# by the 'x86_64' variant.
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_MOVBE := false # Only supported on Atom.
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+
+
+# Some intrinsic functions used by libcxx only exist for prescott or newer CPUs.
+arch_variant_cflags := \
+    -march=prescott \
+
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 783fc77..0946243 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -13,7 +13,7 @@
 
 TARGET_2ND_CPU_ABI := x86
 TARGET_2ND_ARCH := x86
-TARGET_2ND_ARCH_VARIANT := x86
+TARGET_2ND_ARCH_VARIANT := x86_64
 
 TARGET_USES_64_BIT_BINDER := true
 
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index f98a281..9e44263 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -395,8 +395,9 @@
     banner("partition-table")
     AddPartitionTable(output_zip)
 
-  # For devices using A/B update, copy over images from RADIO/ to IMAGES/ and
-  # make sure we have all the needed images ready under IMAGES/.
+  # For devices using A/B update, copy over images from RADIO/ and/or
+  # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
+  # images ready under IMAGES/. All images should have '.img' as extension.
   ab_partitions = os.path.join(OPTIONS.input_tmp, "META", "ab_partitions.txt")
   if os.path.exists(ab_partitions):
     with open(ab_partitions, 'r') as f:
@@ -404,9 +405,17 @@
     for line in lines:
       img_name = line.strip() + ".img"
       img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
+      img_vendor_dir = os.path.join(
+        OPTIONS.input_tmp, "VENDOR_IMAGES")
       if os.path.exists(img_radio_path):
         common.ZipWrite(output_zip, img_radio_path,
                         os.path.join("IMAGES", img_name))
+      else:
+        for root, _, files in os.walk(img_vendor_dir):
+          if img_name in files:
+            common.ZipWrite(output_zip, os.path.join(root, img_name),
+              os.path.join("IMAGES", img_name))
+            break
 
       # Zip spec says: All slashes MUST be forward slashes.
       img_path = 'IMAGES/' + img_name
diff --git a/tools/rgb2565/to565.c b/tools/rgb2565/to565.c
index abf9cdb..94d62ef 100644
--- a/tools/rgb2565/to565.c
+++ b/tools/rgb2565/to565.c
@@ -65,11 +65,11 @@
         out = to565(rb, gb, bb);
         write(1, &out, 2);
 
-#define apply_error(ch) {                                               \
-            next_error[(i-1)*3+ch] += e * 3 / 16;                       \
-            next_error[(i)*3+ch] += e * 5 / 16;                         \
-            next_error[(i+1)*3+ch] += e * 1 / 16;                       \
-            error[(i+1)*3+ch] += e - ((e*1/16) + (e*3/16) + (e*5/16));  \
+#define apply_error(ch) {                                                \
+            next_error[(i-1)*3+(ch)] += e * 3 / 16;                      \
+            next_error[(i)*3+(ch)] += e * 5 / 16;                        \
+            next_error[(i+1)*3+(ch)] += e * 1 / 16;                      \
+            error[(i+1)*3+(ch)] += e - ((e*1/16) + (e*3/16) + (e*5/16)); \
         }
 
         e = r - from565_r(out);
diff --git a/tools/warn.py b/tools/warn.py
index 093b420..135cd51 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -1,12 +1,20 @@
 #!/usr/bin/env python
 # This file uses the following encoding: utf-8
 
+import argparse
 import sys
 import re
 
-if len(sys.argv) == 1:
-    print 'usage: ' + sys.argv[0] + ' <build.log>'
-    sys.exit()
+parser = argparse.ArgumentParser(description='Convert a build log into HTML')
+parser.add_argument('--url',
+                    help='Root URL of an Android source code tree prefixed '
+                    'before files in warnings')
+parser.add_argument('--separator',
+                    help='Separator between the end of a URL and the line '
+                    'number argument. e.g. #')
+parser.add_argument(dest='buildlog', metavar='build.log',
+                    help='Path to build.log file')
+args = parser.parse_args()
 
 # if you add another level, don't forget to give it a color below
 class severity:
@@ -303,6 +311,89 @@
     { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'Java: Unchecked conversion',
         'patterns':[r".*: warning: \[unchecked\] unchecked conversion"] },
+
+    # Warnings from error prone.
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Long literal suffix',
+        'patterns':[r".*: warning: \[LongLiteralLowerCaseSuffix\] Prefer 'L' to 'l' for the suffix to long literal"] },
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Missing @Deprecated',
+        'patterns':[r".*: warning: \[DepAnn\] Deprecated item is not annotated with @Deprecated"] },
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Use of deprecated member',
+        'patterns':[r".*: warning: \[deprecation\] .+ in .+ has been deprecated"] },
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Missing hashCode method',
+        'patterns':[r".*: warning: \[EqualsHashCode\] Classes that override equals should also override hashCode."] },
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Hashtable contains is a legacy method',
+        'patterns':[r".*: warning: \[HashtableContains\] contains\(\) is a legacy method that is equivalent to containsValue\(\)"] },
+    { 'category':'java',    'severity':severity.LOW,   'members':[], 'option':'',
+        'description':'Java: Type parameter used only for return type',
+        'patterns':[r".*: warning: \[TypeParameterUnusedInFormals\] Declaring a type parameter that is only used in the return type is a misuse of generics: operations on the type parameter are unchecked, it hides unsafe casts at invocations of the method, and it interacts badly with method overload resolution."] },
+
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: reference equality used on arrays',
+        'patterns':[r".*: warning: \[ArrayEquals\] Reference equality used to compare arrays"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: hashcode used on array',
+        'patterns':[r".*: warning: \[ArrayHashCode\] hashcode method on array does not hash array contents"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: toString used on an array',
+        'patterns':[r".*: warning: \[ArrayToStringConcatenation\] Implicit toString used on an array \(String \+ Array\)",
+                    r".*: warning: \[ArrayToString\] Calling toString on an array does not provide useful information"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Exception created but not thrown',
+        'patterns':[r".*: warning: \[DeadException\] Exception created but not thrown"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Return or throw from a finally',
+        'patterns':[r".*: warning: \[Finally\] If you return or throw from a finally, then values returned or thrown from the try-catch block will be ignored. Consider using try-with-resources instead."] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Erroneous use of @GuardedBy',
+        'patterns':[r".*: warning: \[GuardedByChecker\] This access should be guarded by '.+'; instead found: '.+'",
+                    r".*: warning: \[GuardedByChecker\] This access should be guarded by '.+', which is not currently held"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Mislabeled Android string',
+        'patterns':[r".*: warning: \[MislabeledAndroidString\] .+ is not \".+\" but \".+\"; prefer .+ for clarity"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Missing cases in enum switch',
+        'patterns':[r".*: warning: \[MissingCasesInEnumSwitch\] Non-exhaustive switch, expected cases for: .+"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Multiple top-level classes (inhibits bug analysis)',
+        'patterns':[r".*: warning: \[MultipleTopLevelClasses\] Expected at most one top-level class declaration, instead found: .+"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: equals method doesn\'t override Object.equals',
+        'patterns':[r".*: warning: \[NonOverridingEquals\] equals method doesn't override Object\.equals.*"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Update of a volatile variable is non-atomic',
+        'patterns':[r".*: warning: \[NonAtomicVolatileUpdate\] This update of a volatile variable is non-atomic"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Return value ignored',
+        'patterns':[r".*: warning: \[ReturnValueIgnored\] Return value of this method must be used",
+                    r".*: warning: \[RectIntersectReturnValueIgnored\] Return value of android.graphics.Rect.intersect\(\) must be checked"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Static variable accessed from an object instance',
+        'patterns':[r".*: warning: \[StaticAccessedFromInstance\] Static (method|variable) .+ should not be accessed from an object instance; instead use .+"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Static guarded by instance',
+        'patterns':[r".*: warning: \[StaticGuardedByInstance\] Write to static variable should not be guarded by instance lock '.+'"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: String reference equality',
+        'patterns':[r".*: warning: \[StringEquality\] String comparison using reference equality instead of value equality"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Synchronization on non-final field',
+        'patterns':[r".*: warning: \[SynchronizeOnNonFinalField\] Synchronizing on non-final fields is not safe: if the field is ever updated, different threads may end up locking on different objects."] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Catch masks fail or assert',
+        'patterns':[r".*: warning: \[TryFailThrowable\] Catching Throwable/Error masks failures from fail\(\) or assert\*\(\) in the try block"] },
+    { 'category':'java',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Java: Wait not in a loop',
+        'patterns':[r".*: warning: \[WaitNotInLoop\] Because of spurious wakeups, a?wait.*\(.*\) must always be called in a loop"] },
+
+    { 'category':'java',    'severity':severity.UNKNOWN,   'members':[], 'option':'',
+        'description':'Java: Unclassified/unrecognized warnings',
+        'patterns':[r".*: warning: \[.+\] .+"] },
+
     { 'category':'aapt',    'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'aapt: No default translation',
         'patterns':[r".*: warning: string '.+' has no default translation in .*"] },
@@ -698,7 +789,7 @@
     output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',)
     cur_row_color = 1 - cur_row_color
     output(text,)
-    output('</td></tr>')
+    output('</td></tr>\n')
 
 def begintable(text, backgroundcolor, extraanchor):
     global anchor
@@ -796,6 +887,19 @@
     if tablestarted:
         endtable()
 
+def warningwithurl(line):
+    if not args.url:
+        return line
+    m = re.search( r'^([^ :]+):(\d+):(.+)', line, re.M|re.I)
+    if not m:
+        return line
+    filepath = m.group(1)
+    linenumber = m.group(2)
+    warning = m.group(3)
+    if args.separator:
+        return '<a href="' + args.url + '/' + filepath + args.separator + linenumber + '">' + filepath + ':' + linenumber + '</a>:' + warning
+    else:
+        return '<a href="' + args.url + '/' + filepath + '">' + filepath + '</a>:' + linenumber + ':' + warning
 
 # dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
 def dumpcategory(cat):
@@ -805,7 +909,7 @@
             header[1:1] = [' (related option: ' + cat['option'] +')']
         begintable(header, colorforseverity(cat['severity']), cat['anchor'])
         for i in cat['members']:
-            tablerow(i)
+            tablerow(warningwithurl(i))
         endtable()
 
 
@@ -835,7 +939,7 @@
         for pat in i['patterns']:
             i['compiledpatterns'].append(re.compile(pat))
 
-infile = open(sys.argv[1], 'r')
+infile = open(args.buildlog, 'r')
 warnings = []
 
 platformversion = 'unknown'
@@ -886,4 +990,3 @@
 dumpseverity(severity.HARMLESS)
 dumpseverity(severity.UNKNOWN)
 dumpfixed()
-