Merge "Move signapk sources to src dir."
diff --git a/core/Makefile b/core/Makefile
index 301e8b2..18e01f9 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -728,6 +728,9 @@
 endif
 endif
 
+ifneq (true,$(TARGET_USERIMAGES_SPARSE_SQUASHFS_DISABLED))
+  INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG := -s
+endif
 ifeq ($(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs)
 INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
 endif
@@ -764,6 +767,7 @@
 $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
 $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1))
+$(if $(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG),$(hide) echo "squashfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG)" >> $(1))
 $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER),$(hide) echo "boot_signer=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1))
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 5ee5edf..7e33660 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -227,6 +227,9 @@
 # dependent binaries of a .toc file will be rebuilt only when the content of
 # the .toc file is changed.
 ###########################################################
+ifndef LOCAL_IS_HOST_MODULE
+# Disable .toc optimization for host modules: we may run the host binaries during the build process
+# and the libraries' implementation matters.
 ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
 LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE).toc
 $(LOCAL_BUILT_MODULE).toc: $(LOCAL_BUILT_MODULE)
@@ -236,6 +239,7 @@
 # Kati adds restat=1 to ninja. GNU make does nothing for this.
 .KATI_RESTAT: $(LOCAL_BUILT_MODULE).toc
 endif
+endif
 
 ###########################################################
 ## logtags: Add .logtags files to global list
diff --git a/core/binary.mk b/core/binary.mk
index 0bbbfcd..4cb62b3 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1202,7 +1202,7 @@
     $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
       $(addsuffix $(so_suffix), \
         $(my_shared_libraries)))
-built_shared_library_tocs := $(addsuffix .toc, $(built_shared_libraries))
+built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
 
 # Add the NDK libraries to the built module dependency
 my_system_shared_libraries_fullpath := \
@@ -1216,7 +1216,13 @@
     $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
       $(addsuffix $(so_suffix), \
         $(installed_shared_library_module_names)))
-built_shared_library_tocs := $(addsuffix .toc, $(built_shared_libraries))
+ifdef LOCAL_IS_HOST_MODULE
+# Disable .toc optimization for host modules: we may run the host binaries during the build process
+# and the libraries' implementation matters.
+built_shared_library_deps := $(built_shared_libraries)
+else
+built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
+endif
 my_system_shared_libraries_fullpath :=
 endif
 
@@ -1312,7 +1318,7 @@
 ###########################################################
 # all_libraries is used for the dependencies on LOCAL_BUILT_MODULE.
 all_libraries := \
-    $(built_shared_library_tocs) \
+    $(built_shared_library_deps) \
     $(my_system_shared_libraries_fullpath) \
     $(built_static_libraries) \
     $(built_whole_libraries)
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index 7885644..06ceecb 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -301,48 +301,6 @@
 force_objclean :=
 
 ###########################################################
-# Clean build tools when swithcing between prebuilt host tools (such as in
-# apps_only build) and tools built from source (platform build).
-previous_prebuilt_tools_config_file := $(HOST_OUT)/previous_prebuilt_tools_config.mk
-ifneq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)))
-current_prebuilt_tools := true
-else
-current_prebuilt_tools := false
-endif
-PREVIOUS_PREBUILT_TOOLS :=
--include $(previous_prebuilt_tools_config_file)
-force_tools_clean :=
-ifdef PREVIOUS_PREBUILT_TOOLS
-ifneq ($(PREVIOUS_PREBUILT_TOOLS),$(current_prebuilt_tools))
-force_tools_clean := true
-endif
-endif # else, this is the first build, so no need to clean.
-
-# Write the new state to the file.
-ifneq ($(PREVIOUS_PREBUILT_TOOLS),$(current_prebuilt_tools))
-$(shell \
-  mkdir -p $(dir $(previous_prebuilt_tools_config_file)) && \
-  echo "PREVIOUS_PREBUILT_TOOLS:=$(current_prebuilt_tools)" > \
-    $(previous_prebuilt_tools_config_file))
-endif
-
-ifeq ($(force_tools_clean),true)
-# For this list of prebuilt tools, see prebuilts/sdk/tools/Android.mk.
-tools_clean_files := \
-  $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/signapk_intermediates \
-  $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/dx_intermediates \
-  $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/shrinkedAndroid_intermediates \
-  $(HOST_OUT)/obj*/EXECUTABLES/aapt_intermediates \
-  $(HOST_OUT)/obj*/EXECUTABLES/aidl_intermediates \
-  $(HOST_OUT)/obj*/EXECUTABLES/zipalign_intermediates \
-  $(HOST_OUT)/obj*/lib/libc++$(HOST_SHLIB_SUFFIX) \
-
-$(info *** build type changed, clean host tools...)
-$(info *** rm -rf $(tools_clean_files))
-$(shell rm -rf $(tools_clean_files))
-endif
-
-###########################################################
 
 .PHONY: clean-jack-files
 clean-jack-files: clean-dex-files
diff --git a/core/combo/TARGET_linux-arm64.mk b/core/combo/TARGET_linux-arm64.mk
index fbf8ab0..bc89bc9 100644
--- a/core/combo/TARGET_linux-arm64.mk
+++ b/core/combo/TARGET_linux-arm64.mk
@@ -115,6 +115,8 @@
 			-Wl,-maarch64linux \
 			-Wl,--hash-style=gnu \
 			-Wl,--fix-cortex-a53-843419 \
+			-fuse-ld=gold \
+			-Wl,--icf=safe \
 			-Wl,--no-undefined-version \
 			$(arch_variant_ldflags)
 
diff --git a/core/config.mk b/core/config.mk
index dbb40f5..556d52b 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -692,6 +692,18 @@
 HOST_CROSS_GLOBAL_CPPFLAGS += $(HOST_CROSS_RELEASE_CPPFLAGS)
 endif
 
+ifdef BRILLO
+# Add a C define that identifies Brillo targets. __BRILLO__ should only be used
+# to differentiate between Brillo and non-Brillo-but-Android environments. Use
+# __ANDROID__ instead to test if something is being built in an Android-derived
+# environment (including Brillo) as opposed to an entirely different
+# environment (e.g. Chrome OS).
+TARGET_GLOBAL_CFLAGS += -D__BRILLO__
+ifdef TARGET_2ND_ARCH
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS += -D__BRILLO__
+endif
+endif
+
 # allow overriding default Java libraries on a per-target basis
 ifeq ($(TARGET_DEFAULT_JAVA_LIBRARIES),)
   TARGET_DEFAULT_JAVA_LIBRARIES := core-libart core-junit ext framework okhttp
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 1bd0bd7..3f52876 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -11,11 +11,6 @@
 DEX2OAT := $(HOST_OUT_EXECUTABLES)/dex2oatd$(HOST_EXECUTABLE_SUFFIX)
 endif
 
-# By default, do not run rerun dex2oat if the tool changes.
-# Comment out the | to force dex2oat to rerun on after all changes.
-DEX2OAT_DEPENDENCY := art/runtime/oat.cc # dependency on oat version number
-DEX2OAT_DEPENDENCY += art/runtime/image.cc # dependency on image version number
-DEX2OAT_DEPENDENCY += |
 DEX2OAT_DEPENDENCY += $(DEX2OAT)
 
 # Use the first preloaded-classes file in PRODUCT_COPY_FILES.
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 1e9de1c..1421761 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -209,6 +209,7 @@
                 \@$(PRIVATE_SRC_LIST_FILE) \
                 -J-Xmx1024m \
                 -XDignore.symbol.file \
+                $(if $(EXPERIMENTAL_USE_JAVA8),-Xdoclint:none) \
                 $(PRIVATE_PROFILING_OPTIONS) \
                 $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
                 $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
diff --git a/core/main.mk b/core/main.mk
index d9ff68e..c29731c 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -525,6 +525,9 @@
 # --mindepth=2 makes the prunes not work.
 subdir_makefiles := \
 	$(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) $(subdirs) Android.mk)
+ifeq ($(USE_SOONG),true)
+subdir_makefiles := $(SOONG_ANDROID_MK) $(subdir_makefiles)
+endif
 
 $(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))
 
@@ -866,6 +869,9 @@
 
 .PHONY: checkbuild
 checkbuild: $(modules_to_check) droid_targets
+ifeq ($(USE_SOONG),true)
+checkbuild: checkbuild-soong
+endif
 ifeq (true,$(ANDROID_BUILD_EVERYTHING_BY_DEFAULT))
 droid: checkbuild
 endif
diff --git a/core/ninja.mk b/core/ninja.mk
index 862ed80..750aae5 100644
--- a/core/ninja.mk
+++ b/core/ninja.mk
@@ -118,21 +118,34 @@
 NINJA_MAKEPARALLEL := $(MAKEPARALLEL) --ninja
 endif
 
+ifeq ($(USE_SOONG),true)
+include $(BUILD_SYSTEM)/soong.mk
+
+COMBINED_BUILD_NINJA := $(OUT_DIR)/combined$(KATI_NINJA_SUFFIX).ninja
+
+$(COMBINED_BUILD_NINJA): $(KATI_BUILD_NINJA) $(SOONG_ANDROID_MK)
+	$(hide) echo "builddir = $(OUT_DIR)" > $(COMBINED_BUILD_NINJA)
+	$(hide) echo "subninja $(SOONG_BUILD_NINJA)" >> $(COMBINED_BUILD_NINJA)
+	$(hide) echo "subninja $(KATI_BUILD_NINJA)" >> $(COMBINED_BUILD_NINJA)
+else
+COMBINED_BUILD_NINJA := $(KATI_BUILD_NINJA)
+endif
+
 $(sort $(DEFAULT_GOAL) $(ANDROID_GOALS)) : ninja_wrapper
 	@#empty
 
 .PHONY: ninja_wrapper
-ninja_wrapper: $(KATI_BUILD_NINJA) $(MAKEPARALLEL)
+ninja_wrapper: $(COMBINED_BUILD_NINJA) $(MAKEPARALLEL)
 	@echo Starting build with ninja
-	+$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && $(NINJA_MAKEPARALLEL) $(NINJA) $(NINJA_GOALS) -C $(TOP) -f $(KATI_BUILD_NINJA) $(NINJA_ARGS)
+	+$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && $(NINJA_MAKEPARALLEL) $(NINJA) $(NINJA_GOALS) -C $(TOP) -f $(COMBINED_BUILD_NINJA) $(NINJA_ARGS)
 
 KATI_FIND_EMULATOR := --use_find_emulator
 ifeq ($(KATI_EMULATE_FIND),false)
   KATI_FIND_EMULATOR :=
 endif
-$(KATI_BUILD_NINJA): $(KATI) $(MAKEPARALLEL) FORCE
+$(KATI_BUILD_NINJA): $(KATI) $(MAKEPARALLEL) $(SOONG_ANDROID_MK) FORCE
 	@echo Running kati to generate build$(KATI_NINJA_SUFFIX).ninja...
-	+$(hide) $(KATI_MAKEPARALLEL) $(KATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true
+	+$(hide) $(KATI_MAKEPARALLEL) $(KATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --no_ignore_dirty=$(SOONG_ANDROID_MK) --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=$(SOONG_ANDROID_MK)
 
 KATI_CXX := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_CFLAGS) $(CLANG_HOST_GLOBAL_CPPFLAGS)
 KATI_LD := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_LDFLAGS)
diff --git a/core/soong.mk b/core/soong.mk
new file mode 100644
index 0000000..c464ba8
--- /dev/null
+++ b/core/soong.mk
@@ -0,0 +1,61 @@
+SOONG_OUT_DIR := $(OUT_DIR)/soong
+SOONG := $(SOONG_OUT_DIR)/soong
+SOONG_BUILD_NINJA := $(SOONG_OUT_DIR)/build.ninja
+SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android.mk
+SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
+SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
+
+ifeq (,$(filter /%,$(SOONG_OUT_DIR)))
+SOONG_TOP_RELPATH := $(shell python -c "import os; print os.path.relpath('$(TOP)', '$(SOONG_OUT_DIR)')")
+else
+SOONG_TOP_RELPATH := $(realpath $(TOP))
+endif
+
+# Bootstrap soong.  Run only the first time for clean builds
+$(SOONG):
+	$(hide) mkdir -p $(dir $@)
+	$(hide) cd $(dir $@) && $(SOONG_TOP_RELPATH)/bootstrap.bash
+
+# Create soong.variables with copies of makefile settings.  Runs every build,
+# but only updates soong.variables if it changes
+SOONG_VARIABLES_TMP := $(SOONG_VARIABLES).$$$$
+$(SOONG_VARIABLES): FORCE
+	$(hide) mkdir -p $(dir $@)
+	$(hide) (\
+	echo '{'; \
+	echo '    "Device_uses_jemalloc": $(if $(filter dlmalloc,$(MALLOC_IMPL)),false,true),'; \
+	echo '    "Device_uses_dlmalloc": $(if $(filter dlmalloc,$(MALLOC_IMPL)),true,false),'; \
+	echo '    $(if $(BOARD_MALLOC_ALIGNMENT),"Dlmalloc_alignment": $(BOARD_MALLOC_ALIGNMENT)$(comma),)'; \
+	echo '    "Platform_sdk_version": $(PLATFORM_SDK_VERSION),'; \
+	echo '    "Unbundled_build": $(if $(TARGET_BUILD_APPS),true,false),'; \
+	echo '    "Brillo": $(if $(BRILLO),true,false),'; \
+	echo ''; \
+	echo '    "DeviceName": "$(TARGET_DEVICE)",'; \
+	echo '    "DeviceArch": "$(TARGET_ARCH)",'; \
+	echo '    "DeviceArchVariant": "$(TARGET_ARCH_VARIANT)",'; \
+	echo '    "DeviceCpuVariant": "$(TARGET_CPU_VARIANT)",'; \
+	echo '    "DeviceAbi": ["$(TARGET_CPU_ABI)", "$(TARGET_CPU_ABI2)"],'; \
+	echo '    "DeviceUsesClang": $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false),'; \
+	echo ''; \
+	echo '    "DeviceSecondaryArch": "$(TARGET_2ND_ARCH)",'; \
+	echo '    "DeviceSecondaryArchVariant": "$(TARGET_2ND_ARCH_VARIANT)",'; \
+	echo '    "DeviceSecondaryCpuVariant": "$(TARGET_2ND_CPU_VARIANT)",'; \
+	echo '    "DeviceSecondaryAbi": ["$(TARGET_2ND_CPU_ABI)", "$(TARGET_2ND_CPU_ABI2)"],'; \
+	echo ''; \
+	echo '    "HostArch": "$(HOST_ARCH)",'; \
+	echo '    "HostSecondaryArch": "$(HOST_2ND_ARCH)"'; \
+	echo '}') > $(SOONG_VARIABLES_TMP); \
+	if ! cmp -s $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); then \
+	  mv $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); \
+	else \
+	  rm $(SOONG_VARIABLES_TMP); \
+	fi
+
+# Tell soong that it is embedded in make
+$(SOONG_IN_MAKE):
+	$(hide) mkdir -p $(dir $@)
+	$(hide) touch $@
+
+# Build an Android.mk listing all soong outputs as prebuilts
+$(SOONG_ANDROID_MK): $(SOONG) $(SOONG_VARIABLES) $(SOONG_IN_MAKE) FORCE
+	$(hide) $(SOONG) $(SOONG_BUILD_NINJA) $(NINJA_ARGS)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index d035036..8b9bdba 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -146,5 +146,5 @@
   # If no BUILD_NUMBER is set, create a useful "I am an engineering build
   # from this date/time" value.  Make it start with a non-digit so that
   # anyone trying to parse it as an integer will probably get "0".
-  BUILD_NUMBER := eng.$(USER).$(shell $(DATE) +%Y%m%d.%H%M%S)
+  BUILD_NUMBER := eng.$(shell echo $${USER:0:6}).$(shell $(DATE) +%Y%m%d.%H%M%S)
 endif
diff --git a/tools/Android.mk b/tools/Android.mk
index 30a064f..9073ac3 100644
--- a/tools/Android.mk
+++ b/tools/Android.mk
@@ -16,17 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-ifeq (,$(TARGET_BUILD_APPS))
-
-ifeq ($(TARGET_BUILD_PDK),true)
-include $(filter-out %/acp/Android.mk %/signapk/Android.mk %/zipalign/Android.mk,\
-  $(call all-makefiles-under,$(LOCAL_PATH)))
-else # !PDK
 include $(call all-makefiles-under,$(LOCAL_PATH))
-endif # PDK
-
-else # TARGET_BUILD_APPS
-
-include $(LOCAL_PATH)/apicheck/Android.mk $(LOCAL_PATH)/ijar/Android.mk
-
-endif
diff --git a/tools/droiddoc/templates-sac/assets/css/default.css b/tools/droiddoc/templates-sac/assets/css/default.css
index c349c89..9b1fe5a 100644
--- a/tools/droiddoc/templates-sac/assets/css/default.css
+++ b/tools/droiddoc/templates-sac/assets/css/default.css
@@ -2208,6 +2208,7 @@
 #nav-swap {
   height:30px;
   border-top:1px solid #ccc;
+  display: none;
 }
 #nav-swap a {
   display:inline-block;
@@ -2242,6 +2243,10 @@
   margin-left:0;
 }
 
+#nav-tree, #swapper {
+  display: none;
+}
+
 #nav-tree ul {
   list-style:none;
   padding:0;
@@ -2336,11 +2341,13 @@
   border-bottom: 1px solid #CCC;
   background:#e9e9e9;
   background: rgba(0, 0, 0, 0.05); /* matches #nav li.expanded */
+  display: none;
 
 }
 #api-nav-title {
   padding:0 5px;
   white-space:nowrap;
+  display: none;
 }
 
 #api-level-toggle {
@@ -3580,8 +3587,9 @@
   border-color: #33b5e5;
 }
 
+// Fudging this so SAC looks OK
 .develop #header .wrap {
-  border-color: #F80;
+  border-color: #CCC;
 }
 
 .distribute #header .wrap {
@@ -4568,3 +4576,83 @@
 .annotation-message {
   display: block;
 }
+
+.dac-custom-search {
+  background: #fff;
+  margin: 0 -10px;
+  padding: 20px 10px;
+  z-index: 1;
+}
+
+.dac-custom-search .dac-fab, .dac-custom-search .dac-button-social {
+  top: -48px;
+}
+
+.dac-custom-search-section-title {
+  color: #505050;
+}
+
+.dac-custom-search-entry {
+  margin-bottom: 36px;
+  margin-top: 24px;
+  margin-left: 0em;
+}
+
+.dac-custom-search-image {
+  background-size: cover;
+  height: 112px;
+}
+
+.dac-custom-search-title {
+  color: #333;
+  font-size: 14px;
+  font-weight: 700;
+  line-height: 0px;
+  padding: 0;
+  margin: 1em 0em 1em 0em;
+}
+
+.dac-custom-search-title a {
+  color: inherit;
+}
+
+.dac-custom-search-section {
+  color: #999;
+  font-size: 16px;
+  font-variant: small-caps;
+  font-weight: 700;
+  margin: -5px 0 0 0;
+}
+
+.dac-custom-search-snippet {
+  color: #666;
+  margin: 0em 0em .25em 0em;
+}
+
+.dac-custom-search-link {
+  font-weight: 500;
+  word-wrap: break-word;
+  width: 100%;
+}
+
+.dac-custom-search-load-more {
+  background: none;
+  border: none;
+  color: #333;
+  cursor: pointer;
+  display: block;
+  font-size: 14px;
+  font-weight: 700;
+  margin: 75px auto;
+  outline: none;
+  padding: 10px;
+}
+
+.dac-custom-search-load-more:hover {
+  opacity: 0.7;
+}
+
+.dac-custom-search-no-results {
+  color: #999;
+}
+
diff --git a/tools/droiddoc/templates-sac/assets/js/docs.js b/tools/droiddoc/templates-sac/assets/js/docs.js
index 0c93780..195c9e5 100644
--- a/tools/droiddoc/templates-sac/assets/js/docs.js
+++ b/tools/droiddoc/templates-sac/assets/js/docs.js
@@ -1630,7 +1630,10 @@
             } else {
               // otherwise, results are already showing, so allow ajax to auto refresh the results
               // and ignore this Enter press to avoid the reload.
-              return false;
+              // return false;
+              //
+              // For now, we're not using AJAX so we respond to every Enter.
+              return true;
             }
         } else if (kd && gSelectedIndex >= 0) {
             window.location = $("a",$('#search_filtered li')[gSelectedIndex]).attr("href");
@@ -1691,6 +1694,11 @@
 
 
         // Search for Google matches
+        /*
+         *  Commented this out because GOOGLE_DATA not defined for us and code
+         *  causes an error.  This probably has to do with the missing
+         *  gms_lists.js file in SAC. TODO figure it all out.
+         *
         for (var i=0; i<GOOGLE_DATA.length; i++) {
             var s = GOOGLE_DATA[i];
             if (text.length != 0 &&
@@ -1703,6 +1711,7 @@
         for (var i=0; i<gGoogleMatches.length; i++) {
             var s = gGoogleMatches[i];
         }
+        */
 
         highlight_autocomplete_result_labels(text);
         sync_selection_table(toroot);
@@ -1830,81 +1839,138 @@
   $("#search_autocomplete").val("").blur();
 
   // reset the ajax search callback to nothing, so results don't appear unless ENTER
-  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {});
+  //  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {});
   return false;
 }
 
 
-
 /* ########################################################## */
 /* ################  CUSTOM SEARCH ENGINE  ################## */
 /* ########################################################## */
 
-google.load('search', '1');
-var searchControl;
+// TODO, add localized search.
+function getLangPref() {
+  return "en";
+}
+
+// Package of functions that does custom search, from DAC redesign.
+(function($) {
+  var LANG;
+
+  function getSearchLang() {
+    if (!LANG) {
+      LANG = getLangPref();
+
+      // Fix zh-cn to be zh-CN.
+      LANG = LANG.replace(/-\w+/, function(m) { return m.toUpperCase(); });
+    }
+    return LANG;
+  }
+
+  function customSearch(query, start) {
+    var searchParams = {
+      // Keys for SAC
+      cx:'016258643462168859875:qqpm8fiwgc0',
+      key: 'AIzaSyBOWHD3JAF6Q9LIJ4NiahGAF70W7iDAI9M',
+
+      // Keys for DAC
+      // cx: '000521750095050289010:zpcpi1ea4s8',
+      // key: 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8',
+
+      q: query,
+      start: start || 1,
+      num: 6,
+      hl: getSearchLang(),
+      fields: 'queries,items(pagemap,link,title,htmlSnippet,formattedUrl)'
+    };
+
+    return $.get('https://content.googleapis.com/customsearch/v1?' +  $.param(searchParams));
+  }
+
+  function renderResults(el, results) {
+    if (!results.items) {
+      el.append($('<div>').text('No results'));
+      return;
+    }
+
+    for (var i = 0; i < results.items.length; i++) {
+      var item = results.items[i];
+      // No thumbnail images in SAC.
+      // var hasImage = item.pagemap && item.pagemap.cse_thumbnail;
+      var sectionMatch = item.link.match(/source\.android\.com\/(\w*)/);
+      var section = (sectionMatch && sectionMatch[1]) || 'blog';
+
+      var entry = $('<div>').addClass('dac-custom-search-entry cols');
+
+// No thumbnail images in SAC.
+//      if (hasImage) {
+//        var image = item.pagemap.cse_thumbnail[0];
+//        entry.append($('<div>').addClass('col-1of6')
+//          .append($('<div>').addClass('dac-custom-search-image').css('background-image', 'url(' + image.src + ')')));
+//      }
+// entry.append($('<div>').addClass(hasImage ? 'col-5of6' : 'col-6of6')
+      entry.append($('<div>')
+        .append($('<p>').addClass('dac-custom-search-section').text(section))
+        .append(
+          $('<a>').text(item.title).attr('href', item.link).wrap('<h2>').parent().addClass('dac-custom-search-title')
+        )
+        .append($('<p>').addClass('dac-custom-search-snippet').html(item.htmlSnippet.replace(/<br>/g, '')))
+        .append($('<a>').addClass('dac-custom-search-link').text(item.formattedUrl).attr('href', item.link)));
+
+      el.append(entry);
+    }
+
+    if (results.queries.nextPage) {
+      var loadMoreButton = $('<button id="dac-custom-search-load-more">')
+        .addClass('dac-custom-search-load-more')
+        .text('Load more')
+        .click(function() {
+          loadMoreResults(el, results);
+        });
+
+      el.append(loadMoreButton);
+    }
+  }
+
+  function loadMoreResults(el, results) {
+    var query = results.queries.request.searchTerms;
+    var start = results.queries.nextPage.startIndex;
+    var loadMoreButton = el.find('#dac-custom-search-load-more');
+
+    loadMoreButton.text('Loading more...');
+
+    customSearch(query, start).then(function(results) {
+      loadMoreButton.remove();
+      renderResults(el, results);
+    });
+  }
+
+  $.fn.customSearch = function(query) {
+    var el = $(this);
+
+    customSearch(query).then(function(results) {
+      el.empty();
+      renderResults(el, results);
+    });
+  };
+})(jQuery);
+
 
 function loadSearchResults() {
-  document.getElementById("search_autocomplete").style.color = "#000";
 
-  // create search control
-  searchControl = new google.search.SearchControl();
-
-  // use our existing search form and use tabs when multiple searchers are used
-  drawOptions = new google.search.DrawOptions();
-  drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_TABBED);
-  drawOptions.setInput(document.getElementById("search_autocomplete"));
-
-  // configure search result options
-  searchOptions = new google.search.SearcherOptions();
-  searchOptions.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
-
-  // Configure s.a.c searchers
-  sacSiteSearcher = new google.search.WebSearch();
-  sacSiteSearcher.setUserDefinedLabel("All");
-  sacSiteSearcher.setSiteRestriction("http://source.android.com/");
-
-  sourceSearcher = new google.search.WebSearch();
-  sourceSearcher.setUserDefinedLabel("Source");
-  sourceSearcher.setSiteRestriction("http://source.android.com/source/");
-
-  devicesSearcher = new google.search.WebSearch();
-  devicesSearcher.setUserDefinedLabel("Devices");
-  devicesSearcher.setSiteRestriction("http://source.android.com/devices/");
-
-  securitySearcher = new google.search.WebSearch();
-  securitySearcher.setUserDefinedLabel("Security");
-  securitySearcher.setSiteRestriction("http://source.android.com/security/");
-
-  compatibilitySearcher = new google.search.WebSearch();
-  compatibilitySearcher.setUserDefinedLabel("Compatibility");
-  compatibilitySearcher.setSiteRestriction("http://source.android.com/compatibility/");
-
-  // add each searcher to the search control
-  searchControl.addSearcher(sacSiteSearcher, searchOptions);
-  searchControl.addSearcher(sourceSearcher, searchOptions);
-  searchControl.addSearcher(devicesSearcher, searchOptions);
-  searchControl.addSearcher(securitySearcher, searchOptions);
-  searchControl.addSearcher(compatibilitySearcher, searchOptions);
+  // Draw the search results box
+  //searchControl.draw(document.getElementById("leftSearchControl"), drawOptions);
+  $(searchResults).append('<div class="leftSearchControl"></div>');
 
 
-  // configure result options
-  searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
-  searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
-  searchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_SHORT);
-  searchControl.setNoResultsString(google.search.SearchControl.NO_RESULTS_DEFAULT_STRING);
-
-  // upon ajax search, refresh the url and search title
-  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {
-    updateResultTitle(query);
-    var query = document.getElementById('search_autocomplete').value;
-    location.hash = 'q=' + query;
-  });
-
-  // draw the search results box
-  searchControl.draw(document.getElementById("leftSearchControl"), drawOptions);
+  // Refresh the url and search title
+  var query = document.getElementById('search_autocomplete').value || getQuery(location.hash);
+  updateResultTitle(query);
+  location.hash = 'q=' + query;
 
   // get query and execute the search
-  searchControl.execute(decodeURI(getQuery(location.hash)));
+  //searchControl.execute(decodeURI(getQuery(location.hash)));
+  $(leftSearchControl).customSearch(getQuery(location.hash));
 
   document.getElementById("search_autocomplete").focus();
   addTabListeners();
@@ -1912,7 +1978,9 @@
 // End of loadSearchResults
 
 google.setOnLoadCallback(function(){
-  if (location.hash.indexOf("q=") == -1) {
+
+  var query = decodeURI(getQuery(location.hash));
+  if (location.hash.indexOf("q=") == -1 || query == '') {
     // if there's no query in the url, don't search and make sure results are hidden
     $('#searchResults').hide();
     return;
@@ -1937,7 +2005,8 @@
 
   // Otherwise, we have a search to do
   var query = decodeURI(getQuery(location.hash));
-  searchControl.execute(query);
+  //searchControl.execute(query);
+  $('#leftSearchControl').customSearch(query);
   $('#searchResults').slideDown('slow');
   $("#search_autocomplete").focus();
   $(".search .close").removeClass("hide");
@@ -1946,7 +2015,10 @@
 });
 
 function updateResultTitle(query) {
-  $("#searchTitle").html("Results for <em>" + escapeHTML(query) + "</em>");
+  $("#searchTitle").html("Results for <em>" + (query) + "</em>");
+// For some reason, the escapeHTML function wasn't working for me.  TODO fix
+// this by copying in a comparable library function.
+//  $("#searchTitle").html("Results for <em>" + escapeHTML(query) + "</em>");
 }
 
 // forcefully regain key-up event control (previously jacked by search api)
@@ -1991,11 +2063,6 @@
 }
 
 
-
-
-
-
-
 /* ######################################################## */
 /* #################  JAVADOC REFERENCE ################### */
 /* ######################################################## */
@@ -2077,7 +2144,9 @@
 
   // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
   var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
-  selectedLevelItem.setAttribute('selected',true);
+//  Another piece of functionality that we don't use that produces an error.
+//  TODO figure it all out.
+//  selectedLevelItem.setAttribute('selected',true);
 }
 
 function changeApiLevel() {
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index cd750e8..2b8d4ee 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -350,7 +350,8 @@
   elif fs_type.startswith("squash"):
     build_command = ["mksquashfsimage.sh"]
     build_command.extend([in_dir, out_file])
-    build_command.extend(["-s"])
+    if "squashfs_sparse_flag" in prop_dict:
+      build_command.extend([prop_dict["squashfs_sparse_flag"]])
     build_command.extend(["-m", prop_dict["mount_point"]])
     if target_out:
       build_command.extend(["-d", target_out])
@@ -478,6 +479,7 @@
 
   common_props = (
       "extfs_sparse_flag",
+      "squashfs_sparse_flag",
       "mkyaffs2_extra_flags",
       "selinux_fc",
       "skip_fsck",