am 1caa938a: Merge "Explictly set WPA_SUPPLICANT_VERSION := VER_0_8_X for the generic devices"

* commit '1caa938a22606a55103318df82a31a92f47900da':
  Explictly set WPA_SUPPLICANT_VERSION := VER_0_8_X for the generic devices
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 877c690..c0525ad 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -205,6 +205,12 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
 
+# 4.4.1
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+
+# 4.4.2
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index fca06fa..8a1175e 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1243,6 +1243,7 @@
 	@# build them.
 	$(hide) mkdir -p $(zip_root)/META
 	$(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
+	$(hide) if test -e $(tool_extensions)/releasetools.py; then $(ACP) $(tool_extensions)/releasetools.py $(zip_root)/META/; fi
 	$(hide)	echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
 	$(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt
 	$(hide) echo "fstab_version=$(PRIVATE_RECOVERY_FSTAB_VERSION)" >> $(zip_root)/META/misc_info.txt
@@ -1262,6 +1263,7 @@
 endif
 	$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
 	$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
 	@# Zip everything up, preserving symlinks
 	$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
index dac07d5..e16560f 100644
--- a/core/copy_headers.mk
+++ b/core/copy_headers.mk
@@ -15,7 +15,9 @@
 $(foreach header,$(LOCAL_COPY_HEADERS), \
   $(eval _chFrom := $(LOCAL_PATH)/$(header)) \
   $(eval _chTo := \
-      $($(my_prefix)OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header))) \
+      $(if $(LOCAL_COPY_HEADERS_TO),\
+        $($(my_prefix)OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header)),\
+        $($(my_prefix)OUT_HEADERS)/$(notdir $(header)))) \
   $(eval $(call copy-one-header,$(_chFrom),$(_chTo))) \
   $(eval all_copied_headers: $(_chTo)) \
  )
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 0d3094d..fd7f338 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -231,6 +231,8 @@
 	@mkdir -p $(dir $@)
 	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rq $$F * )
 
+$(LOCAL_MODULE)-docs.zip : $(out_zip)
+
 $(call dist-for-goals,docs,$(out_zip))
 
 endif
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 40248fc..99283b0 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -41,7 +41,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 := 4.4.3.2.1.000.000
+  PLATFORM_VERSION := 4.4.2
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
diff --git a/target/product/base.mk b/target/product/base.mk
index c8f4354..0959fb4 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -23,6 +23,7 @@
     android.test.runner \
     app_process \
     applypatch \
+    blkid \
     bmgr \
     bugreport \
     content \
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index fc2fc80..159e7b2 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -33,6 +33,8 @@
     bu \
     com.android.location.provider \
     com.android.location.provider.xml \
+    com.android.media.remotedisplay \
+    com.android.media.remotedisplay.xml \
     drmserver \
     framework-res \
     installd \
diff --git a/target/product/full_base.mk b/target/product/full_base.mk
index b2e3189..059697e 100644
--- a/target/product/full_base.mk
+++ b/target/product/full_base.mk
@@ -49,6 +49,9 @@
 # Put en_US first in the list, so make it default.
 PRODUCT_LOCALES := en_US
 
+# Include drawables for all densities
+PRODUCT_AAPT_CONFIG := normal hdpi xhdpi xxhdpi
+
 # Get some sounds
 $(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
 
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index bc59782..4005e57 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -62,7 +62,8 @@
 	SmokeTest \
 	SmokeTestApp \
 	rild \
-	LegacyCamera
+	LegacyCamera \
+	Dialer
 
 # Define the host tools and libs that are parts of the SDK.
 -include sdk/build/product_sdk.mk
diff --git a/tools/droiddoc/templates-ds/jd_lists_unified.cs b/tools/droiddoc/templates-ds/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-ds/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-pdk/jd_lists_unified.cs b/tools/droiddoc/templates-pdk/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-sac/jd_lists_unified.cs b/tools/droiddoc/templates-sac/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-sac/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-sdk/assets/css/default.css b/tools/droiddoc/templates-sdk/assets/css/default.css
index fa9dee3..c3eb8bc 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -393,6 +393,17 @@
   #nav li ul.tree-list-children ul {
     display:block; }
 
+#nav.samples-nav li li li {
+  font-size:13px;
+}
+#nav.samples-nav li li li a {
+  padding-top:3px;
+  padding-bottom:3px;
+}
+#nav.samples-nav li li ul > li:last-child {
+  padding-bottom:3px;
+}
+
 .new,
 .new-child {
   font-size: .78em;
@@ -860,7 +871,40 @@
   .framed-nexus4-port-216 img {
     width: 216px;
     height: 360px; }
+    
+.framed-nexus5-port-span-5 {
+  background: transparent url(../images/styles/device_nexus5_blank_port_span5.png) no-repeat
+  scroll top left;
+  padding: 52px 33px 69px 31px;
+  overflow: hidden;
+}
 
+.framed-nexus5-port-span-5,
+.framed-nexus5-port-span-5 video,
+.framed-nexus5-port-span-5 img {
+  width: 216px;
+  height: 384px;
+}
+
+.framed-nexus5-land-span-13 {
+  background: transparent url(../images/styles/device_nexus5_blank_land_span13.png) no-repeat scroll top left;
+  padding: 36px 119px 54px 108px;
+  overflow: hidden;
+}
+
+.framed-nexus5-land-span-13,
+.framed-nexus5-land-span-13 video,
+.framed-nexus5-land-span-13 img {
+  width: 533px;
+  height: 300px;
+}
+
+.framed-nexus5-port-span-5,
+.framed-nexus5-port-span-5 video,
+.framed-nexus5-port-span-5 img {
+  width: 216px;
+  height: 384px;
+}
 
 /* landing page disclosures */
 .landing-page-link {
@@ -1123,6 +1167,9 @@
   margin-top:5px;
   margin-bottom:5px;
 }
+dl dd dl:first-child {
+  margin-top:0;
+}
 pre strong, pre b, a strong, a b, a code {
     color: inherit;
 }
@@ -1850,6 +1897,10 @@
   font-size:inherit;
 }
 
+.sidebox > *:last-child {
+  margin-bottom:0;
+}
+
 #tb ol,
 #tb ul,
 #qv ul {
@@ -2105,16 +2156,15 @@
   border: solid 1px #ddd;
   background: #f7f7f7;
 }
-.str { color: #080; }
+.str { color: #800; } /* Code string */
 .kwd { color: #008; }
-.com { color: #800; }
 .typ { color: #606; }
 .lit { color: #066; }
 .pun { color: #660; }
 .pln { color: #000; }
 .tag { color: #008; }
 .atn { color: #828; }
-.atv { color: #080; }
+.atv { color: #800; } /* XML string */
 .dec { color: #606; }
 
 /* --------------------------------------------------------------------------
@@ -2213,12 +2263,16 @@
 
 
 /* nav tree */
-#side-nav, #devdoc-nav, #swapper,
+#side-nav, #swapper,
 #nav-tree, #tree-list {
   overflow:hidden;
   margin-left:0;
 }
 
+#devdoc-nav {
+  overflow:visible !important; /* To keep the "to top" button visible */
+}
+
 #nav-tree ul {
   list-style:none;
   padding:0;
@@ -2450,13 +2504,12 @@
   background-position: -10px 0;
 }
 
-
 /* --------------------------------------------------------------------------
-Styles for samples project trees and code browsing in resources tab 
+Styles for samples browser
 */
 
 #codesample-wrapper {
-  width:1000px;
+  width:100000px; /* super wide to contain floats, but doesn't cause scroll */
   overflow:visible;
 }
 pre#codesample-block {
@@ -2465,6 +2518,9 @@
   background:transparent;
   border:none;
 }
+pre#codesample-block a.number {
+  display:none;
+}
 pre#codesample-block .code-line:hover {
   background:#e7e7e7;
 }
@@ -2495,6 +2551,30 @@
   display:inline-block;
 }
 
+/*
+Styles for displaying image or video resources in samples browser.
+Resources are marked as no-display if they exceed the size limit.
+*/
+div#codesample-resource img, div#codesample-resource video {
+  border: 1px solid #ececec;
+}
+
+div#codesample-resource.noDisplay div {
+  border: 1px solid #ececec;
+  width:120px;
+  margin-bottom:4px;
+  padding:20px;
+}
+
+div#codesample-resource .noDisplay-message:after {
+  font-style:italic;
+  font-size:12px;
+  content: 'This resource is not available for browsing. To view it, please download the project.';
+}
+
+/*
+Styles for project structure (treeview) page
+*/
 .structure-dir {
 background-image:url(../../assets/images/folder.png);
 background-repeat:no-repeat;
@@ -2823,7 +2903,9 @@
 }
 
 /* notice box for cross links between Design/Develop docs */
+a.notice-developers-video,
 a.notice-developers,
+a.notice-designers-video,
 a.notice-designers {
   float:right;
   clear:right;
@@ -2832,11 +2914,15 @@
   margin:0 0 20px 20px;
   border:1px solid #ddd;
 }
+a.notice-developers-video.wide,
 a.notice-developers.wide,
+a.notice-designers-video.wide,
 a.notice-designers.wide {
   width:278px;
 }
+a.notice-developers-video div,
 a.notice-developers div,
+a.notice-designers-video div,
 a.notice-designers div {
   min-height:40px;
   background:url('../images/styles/notice-developers@2x.png') no-repeat 10px 10px;
@@ -2847,24 +2933,41 @@
   background:url('../images/styles/notice-designers@2x.png') no-repeat 10px 10px;
   background-size:40px 40px;
 }
+a.notice-designers-video div {
+  background:url('../images/styles/notice-designers-video@2x.png') no-repeat 10px 10px;
+  background-size:40px 40px;
+}
+a.notice-developers-video div {
+  background:url('../images/styles/notice-developers-video@2x.png') no-repeat 10px 10px;
+  background-size:40px 40px;
+}
+a.notice-developers-video:hover,
 a.notice-developers:hover,
+a.notice-designers-video:hover,
 a.notice-designers:hover {
   background:#eee;
 }
+a.notice-developers-video h3,
 a.notice-developers h3,
+a.notice-designers-video h3,
 a.notice-designers h3 {
-  font-size:14px;
-  font-weight:normal;
+  font-size:13px;
+  line-height:18px;
+  font-weight:bold;
   text-transform:uppercase;
   color:#000 !important;
-  margin:0;
+  margin:0 0 1px;
 }
+a.notice-developers-video p,
 a.notice-developers p,
+a.notice-designers-video p,
 a.notice-designers p {
   margin:0;
-  line-height:16px;
+  line-height:14px;
 }
+a.notice-developers-video.left,
 a.notice-developers.left,
+a.notice-designers-video.left,
 a.notice-designers.left {
   margin-left:0;
   float:left;
@@ -4720,25 +4823,32 @@
 
 .landing-banner,
 .landing-docs {
-  margin:20px 0 0;
+  margin:20px 0;
 }
-.landing-banner div:first-child,
-.landing-docs div:first-child,
-.landing-docs .col-12 {
+.landing-banner > div:first-child,
+.landing-docs > div:first-child,
+.landing-docs > .col-12 {
   margin-left:0;
   min-height:280px;
 }
-.landing-banner div:last-child,
-.landing-docs div:last-child,
-.landing-docs .col-12 {
+.landing-banner.short > div {
+  min-height:50px;
+}
+.landing-banner > div:last-child,
+.landing-docs > div:last-child,
+.landing-docs > .col-12 {
   margin-right:0;
 }
 
+.landing-banner > div > *:last-child {
+  margin-bottom:0;
+}
 .landing-banner h1 {
   margin-top:0;
 }
-.landing-docs {
-  clear:left;
+.landing-docs,
+.landing-banner {
+  clear:both;
   overflow:hidden;
 }
 .landing-docs h3 {
@@ -4768,6 +4878,32 @@
 
 
 
+.next-docs {
+  border-top:1px solid #ccc;
+  margin:40px 0 0;
+  padding:5px 0 0;
+  clear:left;
+  overflow:hidden;
+}
+.next-docs div:first-child {
+  margin-left:0;
+}
+.next-docs div:last-child {
+  margin-right:0;
+}
+
+.next-docs h2 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:none;
+  margin:0;
+  padding:5px 0 0;
+}
+
+
+
 /************* HOME/LANDING PAGE *****************/
 
 .slideshow-home {
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_land_span13.png b/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_land_span13.png
new file mode 100644
index 0000000..5d37121
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_land_span13.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_port_span5.png b/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_port_span5.png
new file mode 100644
index 0000000..df35117
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/device_nexus5_blank_port_span5.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video.png b/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video.png
new file mode 100644
index 0000000..eea3485
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video@2x.png b/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video@2x.png
new file mode 100644
index 0000000..a5fdae3
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/notice-designers-video@2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video.png b/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video.png
new file mode 100644
index 0000000..e9f8ed2
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video@2x.png b/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video@2x.png
new file mode 100644
index 0000000..c067ac1
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/notice-developers-video@2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index 1659cc6..1996dac 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -241,7 +241,7 @@
     var training = $(".next-class-link").length; // decides whether to provide "next class" link
     var isCrossingBoundary = false;
 
-    if ($selListItem.hasClass('nav-section')) {
+    if ($selListItem.hasClass('nav-section') && $selListItem.children('div.empty').length == 0) {
       // we're on an index page, jump to the first topic
       $nextLink = $selListItem.find('ul:eq(0)').find('a:eq(0)');
 
@@ -262,12 +262,17 @@
     } else {
       // jump to the next topic in this section (if it exists)
       $nextLink = $selListItem.next('li').find('a:eq(0)');
-      if (!$nextLink.length) {
+      if ($nextLink.length == 0) {
         isCrossingBoundary = true;
         // no more topics in this section, jump to the first topic in the next section
         $nextLink = $selListItem.parents('li:eq(0)').next('li.nav-section').find('a:eq(0)');
         if (!$nextLink.length) {  // Go up another layer to look for next page (lesson > class > course)
           $nextLink = $selListItem.parents('li:eq(1)').next('li.nav-section').find('a:eq(0)');
+          if ($nextLink.length == 0) {
+            // if that doesn't work, we're at the end of the list, so disable NEXT link
+            $('.next-page-link').attr('href','').addClass("disabled")
+                                .click(function() { return false; });
+          }
         }
       }
     }
@@ -285,10 +290,11 @@
       $('.next-page-link').attr('href','')
                           .removeClass("hide").addClass("disabled")
                           .click(function() { return false; });
-
-      $('.next-class-link').attr('href',$nextLink.attr('href'))
-                          .removeClass("hide").append($nextLink.html());
-      $('.next-class-link').find('.new').empty();
+      if ($nextLink.length) {
+        $('.next-class-link').attr('href',$nextLink.attr('href'))
+                             .removeClass("hide").append($nextLink.html());
+        $('.next-class-link').find('.new').empty();
+      }
     } else {
       $('.next-page-link').attr('href', $nextLink.attr('href')).removeClass("hide");
     }
@@ -567,7 +573,7 @@
     } else {
     /* show me */
       // first hide all other siblings
-      var $others = $('li.nav-section.expanded', $(this).closest('ul'));
+      var $others = $('li.nav-section.expanded', $(this).closest('ul')).not('.sticky');
       $others.removeClass('expanded').children('ul').slideUp(250);
 
       // now expand me
@@ -2156,12 +2162,6 @@
 
 // when an event on the browser history occurs (back, forward, load) requery hash and do search
 $(window).hashchange( function(){
-  // Handle hash changes in the samples browser
-  if ($("body").hasClass("samples") && location.href.indexOf("/samples/index.html") != -1) {
-    showSamples();
-    highlightSidenav();
-    resizeNav();
-  }
   // Exit if the hash isn't a search query or there's an error in the query
   if ((location.hash.indexOf("q=") == -1) || (query == "undefined")) {
     // If the results pane is open, close it.
@@ -2382,7 +2382,8 @@
     // Grey things out that aren't available and give a tooltip title
     if (apiLevelNum > selectedLevelNum) {
       obj.addClass("absent").attr("title","Requires API Level \""
-            + apiLevel + "\" or higher");
+            + apiLevel + "\" or higher. To reveal, change the target API level "
+              + "above the left navigation.");
     }
     else obj.removeClass("absent").removeAttr("title");
   });
@@ -2710,6 +2711,9 @@
     $containerUl.append(new_google_node2(node_data));
   }
 
+  // Make all third-generation list items 'sticky' to prevent them from collapsing
+  $containerUl.find('li li li.nav-section').addClass('sticky');
+
   initExpandableNavItems("#"+navtree_id);
 }
 
@@ -2722,9 +2726,11 @@
   var $li = $('<li>');
   var $a;
   if (node_data[NODE_HREF] != null) {
-    $a = $('<a href="' + toRoot + node_data[NODE_HREF] + '">' + linkText + '</a>');
+    $a = $('<a href="' + toRoot + node_data[NODE_HREF] + '" title="' + linkText + '" >'
+        + linkText + '</a>');
   } else {
-    $a = $('<a href="#" onclick="return false;">' + linkText + '/</a>');
+    $a = $('<a href="#" onclick="return false;" title="' + linkText + '" >'
+        + linkText + '/</a>');
   }
   var $childUl = $('<ul>');
   if (node_data[NODE_CHILDREN] != null) {
@@ -2791,9 +2797,18 @@
   $.getScript(toRoot + 'samples_navtree_data.js', function(data, textStatus, jqxhr) {
       // when the file is loaded, initialize the tree
       if(jqxhr.status === 200) {
+          // hack to remove the "about the samples" link then put it back in
+          // after we nuke the list to remove the dummy static list of samples
+          var $firstLi = $("#nav.samples-nav > li:first-child").clone();
+          $("#nav.samples-nav").empty();
+          $("#nav.samples-nav").append($firstLi);
+
           init_google_navtree2("nav.samples-nav", SAMPLES_NAVTREE_DATA);
           highlightSidenav();
           resizeNav();
+          if ($("#jd-content #samples").length) {
+            showSamples();
+          }
       }
   });
 }
@@ -2943,10 +2958,31 @@
         range.moveToElementText(element);
         range.select();
     } else if (window.getSelection) { //all others
-        selection = window.getSelection();        
+        selection = window.getSelection();
         range = doc.createRange();
         range.selectNodeContents(element);
         selection.removeAllRanges();
         selection.addRange(range);
     }
 }
+
+
+
+
+/** Display links and other information about samples that match the
+    group specified by the URL */
+function showSamples() {
+  var group = $("#samples").attr('class');
+  $("#samples").html("<p>Here are some samples for <b>" + group + "</b> apps:</p>");
+
+  var $ul = $("<ul>");
+  $selectedLi = $("#nav li.selected");
+
+  $selectedLi.children("ul").children("li").each(function() {
+      var $li = $("<li>").append($(this).find("a").first().clone());
+      $ul.append($li);
+  });
+
+  $("#samples").append($ul);
+
+}
diff --git a/tools/droiddoc/templates-sdk/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
index 985f059..ed57f1c 100644
--- a/tools/droiddoc/templates-sdk/customizations.cs
+++ b/tools/droiddoc/templates-sdk/customizations.cs
@@ -144,12 +144,8 @@
 <?cs
         include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
 
-
       </div>
-      <script type="text/javascript">
-       showSamplesRefTree();
 
-      </script>
     </div> <!-- end side-nav -->
     <script>
       $(document).ready(function() {
@@ -214,7 +210,8 @@
 <a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
       <div id="api-nav-header">
         <div id="api-level-toggle">
-          <label for="apiLevelCheckbox" class="disabled">API level: </label>
+          <label for="apiLevelCheckbox" class="disabled"
+            title="Select your target API level to dim unavailable APIs">API level: </label>
           <div class="select-wrapper">
             <select id="apiLevelSelector">
               <!-- option elements added by buildApiLevelSelector() -->
@@ -239,7 +236,7 @@
             <div id="packages-nav" class="scroll-pane">
 
               <ul>
-              	<?cs call:package_link_list(docs.packages) ?>
+                <?cs call:package_link_list(docs.packages) ?>
               </ul><br/>
 
             </div> <!-- end packages-nav -->
diff --git a/tools/droiddoc/templates-sdk/docpage.cs b/tools/droiddoc/templates-sdk/docpage.cs
index 6faac04..74c7cd2 100644
--- a/tools/droiddoc/templates-sdk/docpage.cs
+++ b/tools/droiddoc/templates-sdk/docpage.cs
@@ -74,11 +74,20 @@
     <?cs /if ?><?cs # end if training ?>
   </div>
   <?cs /if ?>
+<?cs elif:samplesProjectIndex ?>
+  <div id="api-info-block">
+  <div class="sum-details-links">
+  Overview
+  &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
+  &#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+  </div><!-- end sum-details-links -->
+  </div><!-- end breadcurmb block -->
+  <h1 itemprop="name"><?cs var:projectDir ?></h1>
 <?cs else ?>
   <?cs if:(!fullpage && !header.hide) ?>
     <?cs if:page.landing ?><?cs # header logic for docs that are landing pages ?>
       <div class="landing-banner">
-        <?cs if:page.landing.image ?><?cs # use two-column layout only if there's an image ?>
+        <?cs if:page.landing.image ?><?cs # use two-column layout only if there is an image ?>
         <div class="col-6">
           <img src="<?cs var:toroot ?><?cs var:page.landing.image ?>" alt="" />
         </div>
diff --git a/tools/droiddoc/templates-sdk/head_tag.cs b/tools/droiddoc/templates-sdk/head_tag.cs
index 379829c..54de169 100644
--- a/tools/droiddoc/templates-sdk/head_tag.cs
+++ b/tools/droiddoc/templates-sdk/head_tag.cs
@@ -50,6 +50,7 @@
 /if ?>
 <script type="text/javascript">
   var toRoot = "<?cs var:toroot ?>";
+  var metaTags = [<?cs var:meta.tags ?>];
   var devsite = <?cs if:devsite ?>true<?cs else ?>false<?cs /if ?>;
 </script>
 <script src="<?cs var:toroot ?>assets/js/docs.js" type="text/javascript"></script>
diff --git a/tools/droiddoc/templates-sdk/jd_lists_unified.cs b/tools/droiddoc/templates-sdk/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-sdk/sample.cs b/tools/droiddoc/templates-sdk/sample.cs
index a8eaf8c..04c8d4b 100644
--- a/tools/droiddoc/templates-sdk/sample.cs
+++ b/tools/droiddoc/templates-sdk/sample.cs
@@ -19,17 +19,15 @@
   &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
   &#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
 
-  </div><!-- end sum-details-links -->
-  <div class="api-level">
-  Other info
-  </div>
-</div> <!-- end api-info-block -->
+</div><!-- end sum-details-links -->
+
+</div><!-- end breadcurmb block -->
 
 <div id="jd-header" style="border:0;">
 
 <div id="pathCrumb">
 <?cs each:item = parentdirs ?>
-  <?cs if:pathCrumbLinks
+  <?cs if:LinkifyPathCrumb
     ?><a href="<?cs var:toroot ?><?cs var:item.Link ?>"><?cs var:item.Name ?></a> / 
   <?cs else
     ?><?cs var:item.Name ?> / <?cs /if ?>
@@ -52,35 +50,87 @@
 <?cs var:summary ?>
 
 <!-- begin file contents -->
-<div id="codesample-wrapper">
-<pre id="codesample-line-numbers" class="no-pretty-print hidden"></pre>
-<pre id="codesample-block"><?cs var:fileContents ?></pre>
-</div>
 
-<h3 id="file-location" style="clear:left">Source file location</h3>
-<p>The file containing the source code shown below is located in the corresponding directory in 
-<code>&lt;sdk&gt;/samples/android-&lt;version&gt;/...</code></p>
-
+<?cs # embed image/videos if below maxsize (show message otherwise), else display source code ?>
+<?cs if:resType == "img" ?>
+  <div id="codesample-resource"
+    <?cs if:noDisplay ?>
+      class="noDisplay"><div class="noDisplay-message"></div>
+    <?cs else ?>
+      ><img src="<?cs var:realFile ?>" title="<?cs var:page.title ?>">
+    <?cs /if ?>
+  </div>
+<?cs elif:resType == "video" ?>
+  <div id="codesample-resource"
+    <?cs if:noDisplay ?>
+      class="noDisplay"><div class="noDisplay-message"></div>
+    <?cs else ?>
+      ><video class="play-on-hover" controls style="border:1px solid #ececec;background-color:#f9f9f9;" poster="">
+        <source src="<?cs var:page.title ?>">
+      </video>
+    <?cs /if ?>
+  </div>
+<?cs else ?>
+  <div id="codesample-wrapper">
+    <pre id="codesample-line-numbers" class="no-pretty-print hidden"></pre>
+    <pre id="codesample-block"><?cs var:fileContents ?></pre>
+  </div>
+  <script type="text/javascript">
+  initCodeLineNumbers();
+  </script>
+<?cs /if ?>
 
 <!-- end file contents -->
-<script type="text/javascript">
-  initCodeLineNumbers();
-</script>
-
-
-
 
 <?cs else ?><?cs
   # else, this means it's offline docs,
           so don't show src links (we dont have the pages!) ?>
 
-<p>You can find the source code for this sample in your SDK at:</p>
-<p style="margin-left:2em">
-<code><em>&lt;sdk&gt;</em>/samples/android-<em>&lt;version&gt;</em>/</code>
-</p>
-
 <?cs /if ?><?cs # end if/else online docs ?>
 
+      <div class="content-footer <?cs
+                    if:fullpage ?>wrap<?cs
+                    else ?>layout-content-row<?cs /if ?>"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col <?cs
+                    if:fullpage ?>col-16<?cs
+                    elif:training||guide ?>col-8<?cs
+                    else ?>col-9<?cs /if ?>" style="padding-top:4px">
+          <?cs if:!page.noplus ?><?cs if:fullpage ?><style>#___plusone_0 {float:right !important;}</style><?cs /if ?>
+            <div class="g-plusone" data-size="medium"></div>
+          <?cs /if ?>
+        </div>
+        <?cs if:!fullscreen ?>
+        <div class="paging-links layout-content-col col-4">
+          <?cs if:(design||training||walkthru) && !page.landing && !page.trainingcourse && !footer.hide ?>
+            <a href="#" class="prev-page-link hide"
+                zh-tw-lang="上一堂課"
+                zh-cn-lang="上一课"
+                ru-lang="Предыдущий"
+                ko-lang="이전"
+                ja-lang="前へ"
+                es-lang="Anterior"
+                >Previous</a>
+            <a href="#" class="next-page-link hide"
+                zh-tw-lang="下一堂課"
+                zh-cn-lang="下一课"
+                ru-lang="Следующий"
+                ko-lang="다음"
+                ja-lang="次へ"
+                es-lang="Siguiente"
+                >Next</a>
+          <?cs /if ?>
+        </div>
+        <?cs /if ?>
+      </div>
+
+      <?cs # for training classes, provide a different kind of link when the next page is a different class ?>
+      <?cs if:training && !page.article ?>
+      <div class="layout-content-row content-footer next-class" style="display:none" itemscope itemtype="http://schema.org/SiteNavigationElement">
+          <a href="#" class="next-class-link hide">Next class: </a>
+      </div>
+      <?cs /if ?>
+
   </div> <!-- end jd-content -->
 
 <?cs include:"footer.cs" ?>
diff --git a/tools/droiddoc/templates-sdk/sampleindex.cs b/tools/droiddoc/templates-sdk/sampleindex.cs
index 077b3d5..98767b1 100644
--- a/tools/droiddoc/templates-sdk/sampleindex.cs
+++ b/tools/droiddoc/templates-sdk/sampleindex.cs
@@ -20,12 +20,12 @@
 &#124; Project<?cs else ?>Overview
 &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
 <?cs /if ?>
-&#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+&#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip"
+    onclick="_gaq.push(['_trackEvent', 'Samples', 'Download', <?cs var:projectDir ?>]);"
+    >Download</a>
 
 </div><!-- end sum-details-links -->
-<div class="api-level">
-  Other info
-</div>
+
 </div><!-- end breadcurmb block -->
 
 <h1 itemprop="name"><?cs var:projectDir ?></h1>
@@ -79,12 +79,49 @@
   # else, this means it's offline docs,
           so don't show src links (we dont have the pages!) ?>
 
-<p>You can find the source code for this sample in your SDK at:</p>
-<p style="margin-left:2em">
-<code><em>&lt;sdk&gt;</em>/samples/android-<em>&lt;version&gt;</em>/</code>
-</p>
-
 <?cs /if ?><?cs # end if/else online docs ?>
+      <div class="content-footer <?cs
+                    if:fullpage ?>wrap<?cs
+                    else ?>layout-content-row<?cs /if ?>"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col <?cs
+                    if:fullpage ?>col-16<?cs
+                    elif:training||guide ?>col-8<?cs
+                    else ?>col-9<?cs /if ?>" style="padding-top:4px">
+          <?cs if:!page.noplus ?><?cs if:fullpage ?><style>#___plusone_0 {float:right !important;}</style><?cs /if ?>
+            <div class="g-plusone" data-size="medium"></div>
+          <?cs /if ?>
+        </div>
+        <?cs if:!fullscreen ?>
+        <div class="paging-links layout-content-col col-4">
+          <?cs if:(design||training||walkthru) && !page.landing && !page.trainingcourse && !footer.hide ?>
+            <a href="#" class="prev-page-link hide"
+                zh-tw-lang="上一堂課"
+                zh-cn-lang="上一课"
+                ru-lang="Предыдущий"
+                ko-lang="이전"
+                ja-lang="前へ"
+                es-lang="Anterior"
+                >Previous</a>
+            <a href="#" class="next-page-link hide"
+                zh-tw-lang="下一堂課"
+                zh-cn-lang="下一课"
+                ru-lang="Следующий"
+                ko-lang="다음"
+                ja-lang="次へ"
+                es-lang="Siguiente"
+                >Next</a>
+          <?cs /if ?>
+        </div>
+        <?cs /if ?>
+      </div>
+
+      <?cs # for training classes, provide a different kind of link when the next page is a different class ?>
+      <?cs if:training && !page.article ?>
+      <div class="layout-content-row content-footer next-class" style="display:none" itemscope itemtype="http://schema.org/SiteNavigationElement">
+          <a href="#" class="next-class-link hide">Next class: </a>
+      </div>
+      <?cs /if ?>
 
   </div> <!-- end jd-content -->
 
diff --git a/tools/droiddoc/templates-sdk/sdkpage.cs b/tools/droiddoc/templates-sdk/sdkpage.cs
index ecc26f5..38af569 100644
--- a/tools/droiddoc/templates-sdk/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk/sdkpage.cs
@@ -491,6 +491,7 @@
       $("#sdk-terms-form,.sdk-terms-intro").fadeOut('slow');
       $("#next-steps").fadeIn('slow');
       $("h1#tos-header").text('Get Ready to Code!');
+      _gaq.push(['_trackEvent', 'SDK', 'ADT and Tools', $("#downloadForRealz").html()]);
       return true;
     } else {
       $("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200,
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index a6b9b69..28e8513 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -52,6 +52,11 @@
   -a  (--aslr_mode)  <on|off>
       Specify whether to turn on ASLR for the package (on by default).
 
+  -2  (--two_step)
+      Generate a 'two-step' OTA package, where recovery is updated
+      first, so that any changes made to the system partition are done
+      using the new recovery (new kernel, etc.).
+
 """
 
 import sys
@@ -88,6 +93,7 @@
 OPTIONS.extra_script = None
 OPTIONS.aslr_mode = True
 OPTIONS.worker_threads = 3
+OPTIONS.two_step = False
 
 def MostPopularKey(d, default):
   """Given a dict, return the key corresponding to the largest
@@ -404,6 +410,46 @@
 
   AppendAssertions(script, OPTIONS.info_dict)
   device_specific.FullOTA_Assertions()
+
+  # Two-step package strategy (in chronological order, which is *not*
+  # the order in which the generated script has things):
+  #
+  # if stage is not "2/3" or "3/3":
+  #    write recovery image to boot partition
+  #    set stage to "2/3"
+  #    reboot to boot partition and restart recovery
+  # else if stage is "2/3":
+  #    write recovery image to recovery partition
+  #    set stage to "3/3"
+  #    reboot to recovery partition and restart recovery
+  # else:
+  #    (stage must be "3/3")
+  #    set stage to ""
+  #    do normal full package installation:
+  #       wipe and install system, boot image, etc.
+  #       set up system to update recovery partition on first boot
+  #    complete script normally (allow recovery to mark itself finished and reboot)
+
+  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
+                                         OPTIONS.input_tmp, "RECOVERY")
+  if OPTIONS.two_step:
+    if not OPTIONS.info_dict.get("multistage_support", None):
+      assert False, "two-step packages not supported by this build"
+    fs = OPTIONS.info_dict["fstab"]["/misc"]
+    assert fs.fs_type.upper() == "EMMC", \
+        "two-step packages only supported on devices with EMMC /misc partitions"
+    bcb_dev = {"bcb_dev": fs.device}
+    common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
+    script.AppendExtra("""
+if get_stage("%(bcb_dev)s", "stage") == "2/3" then
+""" % bcb_dev)
+    script.WriteRawImage("/recovery", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "3/3");
+reboot_now("%(bcb_dev)s", "recovery");
+else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
+""" % bcb_dev)
+
   device_specific.FullOTA_InstallBegin()
 
   script.ShowProgress(0.5, 0)
@@ -424,8 +470,6 @@
 
   boot_img = common.GetBootableImage("boot.img", "boot.img",
                                      OPTIONS.input_tmp, "BOOT")
-  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
-                                         OPTIONS.input_tmp, "RECOVERY")
   MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)
 
   Item.GetMetadata(input_zip)
@@ -445,6 +489,19 @@
     script.AppendExtra(OPTIONS.extra_script)
 
   script.UnmountAll()
+
+  if OPTIONS.two_step:
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "");
+""" % bcb_dev)
+    script.AppendExtra("else\n")
+    script.WriteRawImage("/boot", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "2/3");
+reboot_now("%(bcb_dev)s", "");
+endif;
+endif;
+""" % bcb_dev)
   script.AddToZip(input_zip, output_zip)
   WriteMetadata(metadata, output_zip)
 
@@ -560,7 +617,8 @@
       OPTIONS.source_info_dict)
   target_boot = common.GetBootableImage(
       "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
-  updating_boot = (source_boot.data != target_boot.data)
+  updating_boot = (not OPTIONS.two_step and
+                   (source_boot.data != target_boot.data))
 
   source_recovery = common.GetBootableImage(
       "/tmp/recovery.img", "recovery.img", OPTIONS.source_tmp, "RECOVERY",
@@ -578,6 +636,46 @@
   AppendAssertions(script, OPTIONS.target_info_dict)
   device_specific.IncrementalOTA_Assertions()
 
+  # Two-step incremental package strategy (in chronological order,
+  # which is *not* the order in which the generated script has
+  # things):
+  #
+  # if stage is not "2/3" or "3/3":
+  #    do verification on current system
+  #    write recovery image to boot partition
+  #    set stage to "2/3"
+  #    reboot to boot partition and restart recovery
+  # else if stage is "2/3":
+  #    write recovery image to recovery partition
+  #    set stage to "3/3"
+  #    reboot to recovery partition and restart recovery
+  # else:
+  #    (stage must be "3/3")
+  #    perform update:
+  #       patch system files, etc.
+  #       force full install of new boot image
+  #       set up system to update recovery partition on first boot
+  #    complete script normally (allow recovery to mark itself finished and reboot)
+
+  if OPTIONS.two_step:
+    if not OPTIONS.info_dict.get("multistage_support", None):
+      assert False, "two-step packages not supported by this build"
+    fs = OPTIONS.info_dict["fstab"]["/misc"]
+    assert fs.fs_type.upper() == "EMMC", \
+        "two-step packages only supported on devices with EMMC /misc partitions"
+    bcb_dev = {"bcb_dev": fs.device}
+    common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
+    script.AppendExtra("""
+if get_stage("%(bcb_dev)s", "stage") == "2/3" then
+""" % bcb_dev)
+    script.AppendExtra("sleep(20);\n");
+    script.WriteRawImage("/recovery", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "3/3");
+reboot_now("%(bcb_dev)s", "recovery");
+else if get_stage("%(bcb_dev)s", "stage") != "3/3" then
+""" % bcb_dev)
+
   script.Print("Verifying current system...")
 
   device_specific.IncrementalOTA_VerifyBegin()
@@ -615,10 +713,23 @@
 
   device_specific.IncrementalOTA_VerifyEnd()
 
+  if OPTIONS.two_step:
+    script.WriteRawImage("/boot", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "2/3");
+reboot_now("%(bcb_dev)s", "");
+else
+""" % bcb_dev)
+
   script.Comment("---- start making changes here ----")
 
   device_specific.IncrementalOTA_InstallBegin()
 
+  if OPTIONS.two_step:
+    common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
+    script.WriteRawImage("/boot", "boot.img")
+    print "writing full boot image (forced by two-step mode)"
+
   if OPTIONS.wipe_user_data:
     script.Print("Erasing user data...")
     script.FormatPartition("/data")
@@ -646,23 +757,24 @@
     so_far += tf.size
     script.SetProgress(so_far / total_patch_size)
 
-  if updating_boot:
-    # Produce the boot image by applying a patch to the current
-    # contents of the boot partition, and write it back to the
-    # partition.
-    script.Print("Patching boot image...")
-    script.ApplyPatch("%s:%s:%d:%s:%d:%s"
-                      % (boot_type, boot_device,
-                         source_boot.size, source_boot.sha1,
-                         target_boot.size, target_boot.sha1),
-                      "-",
-                      target_boot.size, target_boot.sha1,
-                      source_boot.sha1, "patch/boot.img.p")
-    so_far += target_boot.size
-    script.SetProgress(so_far / total_patch_size)
-    print "boot image changed; including."
-  else:
-    print "boot image unchanged; skipping."
+  if not OPTIONS.two_step:
+    if updating_boot:
+      # Produce the boot image by applying a patch to the current
+      # contents of the boot partition, and write it back to the
+      # partition.
+      script.Print("Patching boot image...")
+      script.ApplyPatch("%s:%s:%d:%s:%d:%s"
+                        % (boot_type, boot_device,
+                           source_boot.size, source_boot.sha1,
+                           target_boot.size, target_boot.sha1),
+                        "-",
+                        target_boot.size, target_boot.sha1,
+                        source_boot.sha1, "patch/boot.img.p")
+      so_far += target_boot.size
+      script.SetProgress(so_far / total_patch_size)
+      print "boot image changed; including."
+    else:
+      print "boot image unchanged; skipping."
 
   if updating_recovery:
     # Recovery is generated as a patch using both the boot image
@@ -747,6 +859,13 @@
     script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1, sf.sha1, "patch/"+fn+".p")
   script.SetPermissions("/system/build.prop", 0, 0, 0644, None, None)
 
+  if OPTIONS.two_step:
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "");
+endif;
+endif;
+""" % bcb_dev)
+
   script.AddToZip(target_zip, output_zip)
   WriteMetadata(metadata, output_zip)
 
@@ -773,12 +892,14 @@
         OPTIONS.aslr_mode = False
     elif o in ("--worker_threads"):
       OPTIONS.worker_threads = int(a)
+    elif o in ("-2", "--two_step"):
+      OPTIONS.two_step = True
     else:
       return False
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:k:i:d:wne:a:",
+                             extra_opts="b:k:i:d:wne:a:2",
                              extra_long_opts=["board_config=",
                                               "package_key=",
                                               "incremental_from=",
@@ -787,6 +908,7 @@
                                               "extra_script=",
                                               "worker_threads=",
                                               "aslr_mode=",
+                                              "two_step",
                                               ],
                              extra_option_handler=option_handler)