Merge change 7040 into donut

* changes:
  CTS: Add media test cases to CTS makefile
diff --git a/core/base_rules.mk b/core/base_rules.mk
index c182a77..a6bf504 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -392,6 +392,25 @@
 
 endif # !LOCAL_UNINSTALLABLE_MODULE
 
+
+###########################################################
+## CHECK_BUILD goals
+###########################################################
+
+# If nobody has defined a more specific module for the
+# checked modules, use LOCAL_BUILT_MODULE.  This was old
+# behavior, so it should be a safe default.
+ifndef LOCAL_CHECKED_MODULE
+  LOCAL_CHECKED_MODULE := $(LOCAL_BUILT_MODULE)
+endif
+
+# If they request that this module not be checked, then don't.
+# PLEASE DON'T SET THIS.  ANY PLACES THAT SET THIS WITHOUT
+# GOOD REASON WILL HAVE IT REMOVED.
+ifdef LOCAL_DONT_CHECK_MODULE
+  LOCAL_CHECKED_MODULE :=
+endif
+
 ###########################################################
 ## Register with ALL_MODULES
 ###########################################################
@@ -404,6 +423,8 @@
     $(ALL_MODULES.$(LOCAL_MODULE).PATH) $(LOCAL_PATH)
 ALL_MODULES.$(LOCAL_MODULE).TAGS := \
     $(ALL_MODULES.$(LOCAL_MODULE).TAGS) $(LOCAL_MODULE_TAGS)
+ALL_MODULES.$(LOCAL_MODULE).CHECKED := \
+    $(ALL_MODULES.$(LOCAL_MODULE).CHECKED) $(LOCAL_CHECKED_MODULE)
 ALL_MODULES.$(LOCAL_MODULE).BUILT := \
     $(ALL_MODULES.$(LOCAL_MODULE).BUILT) $(LOCAL_BUILT_MODULE)
 ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
@@ -430,9 +451,6 @@
 $(foreach tag,$(LOCAL_MODULE_TAGS),\
     $(eval ALL_MODULE_NAME_TAGS.$(tag) += $(LOCAL_MODULE)))
 
-# Always build everything, but only install a subset.
-ALL_BUILT_MODULES += $(LOCAL_BUILT_MODULE)
-
 ###########################################################
 ## NOTICE files
 ###########################################################
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index b2e95b4..031bc0b 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -5,6 +5,8 @@
 LOCAL_MODULE:=
 LOCAL_MODULE_PATH:=
 LOCAL_MODULE_STEM:=
+LOCAL_DONT_CHECK_MODULE:=
+LOCAL_CHECKED_MODULE:=
 LOCAL_BUILT_MODULE:=
 LOCAL_BUILT_MODULE_STEM:=
 OVERRIDE_BUILT_MODULE_PATH:=
diff --git a/core/definitions.mk b/core/definitions.mk
index e66c6b8..c84cbd8 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -41,9 +41,6 @@
 # set of installed targets.
 ALL_DEFAULT_INSTALLED_MODULES:=
 
-# Full paths to all targets that will be built.
-ALL_BUILT_MODULES:=
-
 # The list of tags that have been defined by
 # LOCAL_MODULE_TAGS.  Each word in this variable maps
 # to a corresponding ALL_MODULE_TAGS.<tagname> variable
@@ -1239,21 +1236,21 @@
 $(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR)
 $(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES), \
     $(PRIVATE_CLASS_INTERMEDIATES_DIR))
-$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_INTERMEDIATES_DIR)/java-source-list)
+$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list)
 $(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
-	    find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_INTERMEDIATES_DIR)/java-source-list; \
+	    find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list; \
 fi
-$(hide) tr ' ' '\n' < $(PRIVATE_INTERMEDIATES_DIR)/java-source-list \
-    | sort -u > $(PRIVATE_INTERMEDIATES_DIR)/java-source-list-uniq
+$(hide) tr ' ' '\n' < $(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list \
+    | sort -u > $(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list-uniq
 $(hide) $(TARGET_JAVAC) -encoding ascii $(PRIVATE_BOOTCLASSPATH) \
     $(addprefix -classpath ,$(strip \
         $(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
     $(strip $(PRIVATE_JAVAC_DEBUG_FLAGS)) $(xlint_unchecked) \
     -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
-    \@$(PRIVATE_INTERMEDIATES_DIR)/java-source-list-uniq \
+    \@$(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list-uniq \
     || ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 )
-$(hide) rm -f $(PRIVATE_INTERMEDIATES_DIR)/java-source-list
-$(hide) rm -f $(PRIVATE_INTERMEDIATES_DIR)/java-source-list-uniq
+$(hide) rm -f $(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list
+$(hide) rm -f $(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list-uniq
 $(hide) mkdir -p $(dir $@)
 $(hide) jar $(if $(strip $(PRIVATE_JAR_MANIFEST)),-cfm,-cf) \
     $@ $(PRIVATE_JAR_MANIFEST) -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
diff --git a/core/java.mk b/core/java.mk
index 5a434c4..658b173 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -37,6 +37,54 @@
 $(error LOCAL_BUILT_MODULE_STEM may not be "$(LOCAL_BUILT_MODULE_STEM)")
 endif
 
+
+##############################################################################
+# Define the intermediate targets before including base_rules so they get
+# the correct environment.
+##############################################################################
+
+intermediates := $(call local-intermediates-dir)
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
+# This is cleared below, and re-set if we really need it.
+full_classes_jar := $(intermediates.COMMON)/classes.jar
+
+# Emma source code coverage
+ifneq ($(EMMA_INSTRUMENT),true)
+LOCAL_NO_EMMA_INSTRUMENT := true
+LOCAL_NO_EMMA_COMPILE := true
+endif
+
+# Choose leaf name for the compiled jar file.
+ifneq ($(LOCAL_NO_EMMA_COMPILE),true)
+full_classes_compiled_jar_leaf := classes-no-debug-var.jar
+else
+full_classes_compiled_jar_leaf := classes-full-debug.jar
+endif
+full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
+
+emma_intermediates_dir := $(intermediates.COMMON)/emma_out
+# the 'lib/$(full_classes_compiled_jar_leaf)' portion of this path is fixed in
+# the emma tool
+full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
+full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
+full_classes_jarjar_jar := $(full_classes_jar)
+built_dex := $(intermediates.COMMON)/classes.dex
+
+LOCAL_INTERMEDIATE_TARGETS += \
+    $(full_classes_jar) \
+    $(full_classes_compiled_jar) \
+    $(full_classes_emma_jar) \
+    $(full_classes_stubs_jar) \
+    $(full_classes_jarjar_jar) \
+    $(built_dex)
+
+
+# TODO: It looks like the only thing we need from base_rules is
+# all_java_sources.  See if we can get that by adding a
+# common_java.mk, and moving the include of base_rules.mk to
+# after all the declarations.
+
 #######################################
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
@@ -65,6 +113,7 @@
 # LOCAL_BUILT_MODULE, so it will inherit the necessary PRIVATE_*
 # variable definitions.
 full_classes_jar := $(intermediates.COMMON)/classes.jar
+built_dex := $(intermediates.COMMON)/classes.dex
 
 # Droiddoc isn't currently able to generate stubs for modules, so we're just
 # allowing it to use the classes.jar as the "stubs" that would be use to link
@@ -74,34 +123,28 @@
 #   it, so it's closest to what's on the device.
 # - This extra copy, with the dependency on LOCAL_BUILT_MODULE allows the
 #   PRIVATE_ vars to be preserved.
-full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 $(full_classes_stubs_jar): PRIVATE_SOURCE_FILE := $(full_classes_jar)
 $(full_classes_stubs_jar) : $(LOCAL_BUILT_MODULE) | $(ACP)
 	@echo Copying $(PRIVATE_SOURCE_FILE)
 	$(hide) $(ACP) -fp $(PRIVATE_SOURCE_FILE) $@
 ALL_MODULES.$(LOCAL_MODULE).STUBS := $(full_classes_stubs_jar)
 
-# Emma source code coverage
-ifneq ($(EMMA_INSTRUMENT),true) 
-LOCAL_NO_EMMA_INSTRUMENT := true
-LOCAL_NO_EMMA_COMPILE := true
-endif
-
-# Choose leaf name for the compiled jar file.
-ifneq ($(LOCAL_NO_EMMA_COMPILE),true) 
-full_classes_compiled_jar_leaf := classes-no-debug-var.jar
-else
-full_classes_compiled_jar_leaf := classes-full-debug.jar
-endif
-
 # Compile the java files to a .jar file.
 # This intentionally depends on java_sources, not all_java_sources.
 # Deps for generated source files must be handled separately,
 # via deps on the target that generates the sources.
-full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
 $(full_classes_compiled_jar): $(java_sources) $(full_java_lib_deps)
 	$(transform-java-to-classes.jar)
 
+# All of the rules after full_classes_compiled_jar are very unlikely
+# to fail except for bugs in their respective tools.  If you would
+# like to run these rules, add the "all" modifier goal to the make
+# command line.
+# This overwrites the value defined in base_rules.mk.  That's a little
+# dirty.  It's preferable to set LOCAL_CHECKED_MODULE, but this has to
+# be done after the inclusion of base_rules.mk.
+ALL_MODULES.$(LOCAL_MODULE).CHECKED := $(full_classes_compiled_jar)
+
 ifneq ($(LOCAL_NO_EMMA_COMPILE),true) 
 # If you instrument class files that have local variable debug information in
 # them emma does not correctly maintain the local variable table.
@@ -115,11 +158,6 @@
 $(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
 endif
 
-emma_intermediates_dir := $(intermediates.COMMON)/emma_out
-# the 'lib/$(full_classes_compiled_jar_leaf)' portion of this path is fixed in 
-# the emma tool
-full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
-
 ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 # Skip adding emma instrumentation to class files if this is a static library,
 # since it will be instrumented by the package that includes it
@@ -142,7 +180,6 @@
 
 # Run jarjar if necessary, otherwise just copy the file.  This is the last
 # part of this step, so the output of this command is full_classes_jar.
-full_classes_jarjar_jar := $(full_classes_jar)
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_emma_jar) | jarjar
@@ -154,9 +191,6 @@
 	$(hide) $(ACP) $< $@
 endif
 
-
-built_dex := $(intermediates.COMMON)/classes.dex
-
 # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
 # will work even when intermediates != intermediates.COMMON.
 $(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
diff --git a/core/main.mk b/core/main.mk
index fb1a58f..2c7bb78 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -126,7 +126,7 @@
 # These are the modifier targets that don't do anything themselves, but
 # change the behavior of the build.
 # (must be defined before including definitions.make)
-INTERNAL_MODIFIER_TARGETS := showcommands
+INTERNAL_MODIFIER_TARGETS := showcommands checkbuild
 
 # Bring in standard build system definitions.
 include $(BUILD_SYSTEM)/definitions.mk
@@ -292,11 +292,11 @@
 endif
 
 
-# If all they typed was make showcommands, we'll actually build
-# the default target.
-ifeq ($(MAKECMDGOALS),showcommands)
-.PHONY: showcommands
-showcommands: $(DEFAULT_GOAL)
+# If they only used the modifier goals (showcommands, checkbuild), we'll actually
+# build the default target.
+ifeq ($(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS)),)
+.PHONY: $(INTERNAL_MODIFIER_TARGETS)
+$(INTERNAL_MODIFIER_TARGETS): $(DEFAULT_GOAL)
 endif
 
 # These targets are going to delete stuff, don't bother including
@@ -530,7 +530,6 @@
 # poisons the rest of the tags and shouldn't appear
 # on any list.
 Default_MODULES := $(sort $(ALL_DEFAULT_INSTALLED_MODULES) \
-                          $(ALL_BUILT_MODULES) \
                           $(CUSTOM_MODULES))
 # TODO: Remove the 3 places in the tree that use
 # ALL_DEFAULT_INSTALLED_MODULES and get rid of it from this list.
@@ -596,7 +595,7 @@
 endif
 
 
-# config/Makefile contains extra stuff that we don't want to pollute this
+# build/core/Makefile contains extra stuff that we don't want to pollute this
 # top-level makefile with.  It expects that ALL_DEFAULT_INSTALLED_MODULES
 # contains everything that's built during the current make, but it also further
 # extends ALL_DEFAULT_INSTALLED_MODULES.
@@ -607,6 +606,20 @@
 
 endif # dont_bother
 
+# These are additional goals that we build, in order to make sure that there
+# is as little code as possible in the tree that doesn't build.
+modules_to_check := $(foreach m,$(ALL_MODULES),$(ALL_MODULES.$(m).CHECKED))
+
+# If you would like to build all goals, and not skip any intermediate
+# steps, you can pass the "all" modifier goal on the commandline.
+ifneq ($(filter all,$(MAKECMDGOALS)),)
+modules_to_check += $(foreach m,$(ALL_MODULES),$(ALL_MODULES.$(m).BUILT))
+endif
+
+# for easier debugging
+modules_to_check := $(sort $(modules_to_check))
+#$(error modules_to_check $(modules_to_check))
+
 # -------------------------------------------------------------------
 # This is used to to get the ordering right, you can also use these,
 # but they're considered undocumented, so don't complain if their
@@ -624,10 +637,16 @@
 
 # All the droid stuff, in directories
 .PHONY: files
-files: prebuilt $(modules_to_install) $(INSTALLED_ANDROID_INFO_TXT_TARGET)
+files: prebuilt \
+        $(modules_to_install) \
+        $(modules_to_check) \
+        $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 
 # -------------------------------------------------------------------
 
+.PHONY: checkbuild
+checkbuild: $(modules_to_check)
+
 .PHONY: ramdisk
 ramdisk: $(INSTALLED_RAMDISK_TARGET)
 
diff --git a/tools/applypatch/imgdiff.c b/tools/applypatch/imgdiff.c
index f0b5fea..6d610e6 100644
--- a/tools/applypatch/imgdiff.c
+++ b/tools/applypatch/imgdiff.c
@@ -439,6 +439,77 @@
   ch->len = ch->gzip_len;
 }
 
+/*
+ * Return true if the data in the chunk is identical (including the
+ * compressed representation, for gzip chunks).
+ */
+int AreChunksEqual(ImageChunk* a, ImageChunk* b) {
+    if (a->type != b->type) return 0;
+
+    switch (a->type) {
+        case CHUNK_NORMAL:
+            return a->len == b->len && memcmp(a->data, b->data, a->len) == 0;
+
+        case CHUNK_GZIP:
+            return a->gzip_len == b->gzip_len &&
+                memcmp(a->gzip_data, b->gzip_data, a->gzip_len) == 0;
+
+        default:
+            fprintf(stderr, "unknown chunk type %d\n", a->type);
+            return 0;
+    }
+}
+
+/*
+ * Look for runs of adjacent normal chunks and compress them down into
+ * a single chunk.  (Such runs can be produced when gzip chunks are
+ * changed to normal chunks.)
+ */
+void MergeAdjacentNormalChunks(ImageChunk* chunks, int* num_chunks) {
+  int out = 0;
+  int in_start = 0, in_end;
+  while (in_start < *num_chunks) {
+    if (chunks[in_start].type != CHUNK_NORMAL) {
+      in_end = in_start+1;
+    } else {
+      // in_start is a normal chunk.  Look for a run of normal chunks
+      // that constitute a solid block of data (ie, each chunk begins
+      // where the previous one ended).
+      for (in_end = in_start+1;
+           in_end < num_chunks && chunks[in_end].type == CHUNK_NORMAL &&
+             (chunks[in_end].start ==
+              chunks[in_end-1].start + chunks[in_end-1].len &&
+              chunks[in_end].data ==
+              chunks[in_end-1].data + chunks[in_end-1].len);
+           ++in_end);
+    }
+
+    if (in_end == in_start+1) {
+      if (out != in_start) {
+        memcpy(chunks+out, chunks+in_start, sizeof(ImageChunk));
+      }
+    } else {
+      printf("collapse normal chunks %d - %d\n", in_start, in_end-1);
+
+      // Merge chunks [in_start, in_end-1] into one chunk.  Since the
+      // data member of each chunk is just a pointer into an in-memory
+      // copy of the file, this can be done without recopying (the
+      // output chunk has the first chunk's start location and data
+      // pointer, and length equal to the sum of the input chunk
+      // lengths).
+      chunks[out].type = CHUNK_NORMAL;
+      chunks[out].start = chunks[in_start].start;
+      chunks[out].data = chunks[in_start].data;
+      chunks[out].len = chunks[in_end-1].len +
+        (chunks[in_end-1].start - chunks[in_start].start);
+    }
+
+    ++out;
+    in_start = in_end;
+  }
+  *num_chunks = out;
+}
+
 int main(int argc, char** argv) {
   if (argc != 4) {
     fprintf(stderr, "usage: %s <src-img> <tgt-img> <patch-file>\n", argv[0]);
@@ -475,24 +546,47 @@
     }
   }
 
-  // Confirm that given the uncompressed chunk data in the target, we
-  // can recompress it and get exactly the same bits as are in the
-  // input target image.  If this fails, treat the chunk as a normal
-  // non-gzipped chunk.
-
   for (i = 0; i < num_tgt_chunks; ++i) {
     if (tgt_chunks[i].type == CHUNK_GZIP) {
+      // Confirm that given the uncompressed chunk data in the target, we
+      // can recompress it and get exactly the same bits as are in the
+      // input target image.  If this fails, treat the chunk as a normal
+      // non-gzipped chunk.
       if (ReconstructGzipChunk(tgt_chunks+i) < 0) {
         printf("failed to reconstruct target gzip chunk %d; "
                "treating as normal chunk\n", i);
         ChangeGzipChunkToNormal(tgt_chunks+i);
         ChangeGzipChunkToNormal(src_chunks+i);
+        continue;
       } else {
         printf("reconstructed target gzip chunk %d\n", i);
       }
+
+      // If two gzip chunks are identical (eg, the kernel has not
+      // changed between two builds), treat them as normal chunks.
+      // This makes applypatch much faster -- it can apply a trivial
+      // patch to the compressed data, rather than uncompressing and
+      // recompressing to apply the trivial patch to the uncompressed
+      // data.
+      if (AreChunksEqual(tgt_chunks+i, src_chunks+i)) {
+        printf("source and target chunk %d are identical; "
+               "treating as normal chunk\n", i);
+        ChangeGzipChunkToNormal(tgt_chunks+i);
+        ChangeGzipChunkToNormal(src_chunks+i);
+      }
     }
   }
 
+  // If we changed any gzip chunks to normal chunks, we can simplify
+  // the patch by merging neighboring normal chunks.
+  MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
+  MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
+  if (num_src_chunks != num_tgt_chunks) {
+    // This shouldn't happen.
+    fprintf(stderr, "merging normal chunks went awry\n");
+    return 1;
+  }
+
   // Compute bsdiff patches for each chunk's data (the uncompressed
   // data, in the case of gzip chunks).
 
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index fb55028..caf7935 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -304,9 +304,14 @@
         pkcs7.encodeSignedData(out);
     }
 
-    /** Copy all the files in a manifest from input to output. */
+    /**
+     * Copy all the files in a manifest from input to output.  We set
+     * the modification times in the output to a fixed time, so as to
+     * reduce variation in the output file and make incremental OTAs
+     * more efficient.
+     */
     private static void copyFiles(Manifest manifest,
-            JarFile in, JarOutputStream out) throws IOException {
+        JarFile in, JarOutputStream out, long timestamp) throws IOException {
         byte[] buffer = new byte[4096];
         int num;
 
@@ -315,15 +320,16 @@
         Collections.sort(names);
         for (String name : names) {
             JarEntry inEntry = in.getJarEntry(name);
+            JarEntry outEntry = null;
             if (inEntry.getMethod() == JarEntry.STORED) {
                 // Preserve the STORED method of the input entry.
-                out.putNextEntry(new JarEntry(inEntry));
+                outEntry = new JarEntry(inEntry);
             } else {
                 // Create a new entry so that the compressed len is recomputed.
-                JarEntry je = new JarEntry(name);
-                je.setTime(inEntry.getTime());
-                out.putNextEntry(je);
+                outEntry = new JarEntry(name);
             }
+            outEntry.setTime(timestamp);
+            out.putNextEntry(outEntry);
 
             InputStream data = in.getInputStream(inEntry);
             while ((num = data.read(buffer)) > 0) {
@@ -380,7 +386,7 @@
             writeSignatureBlock(signature, publicKey, outputJar);
 
             // Everything else
-            copyFiles(manifest, inputJar, outputJar);
+            copyFiles(manifest, inputJar, outputJar, timestamp);
         } catch (Exception e) {
             e.printStackTrace();
             System.exit(1);