am 99bb0365: am 948206c0: Merge "Fix tools path on Mac OS for java 7."
* commit '99bb0365d53186c8ece6ac4e61ca2d303d0e0f0a':
Fix tools path on Mac OS for java 7.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index c912497..c0525ad 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -208,6 +208,9 @@
# 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 a8a7d97..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,7 +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 "update_rename_support=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/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/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 c4b81d2..c3eb8bc 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -1897,6 +1897,10 @@
font-size:inherit;
}
+.sidebox > *:last-child {
+ margin-bottom:0;
+}
+
#tb ol,
#tb ul,
#qv ul {
@@ -2259,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;
@@ -2497,7 +2505,7 @@
}
/* --------------------------------------------------------------------------
-Styles for samples project trees and code browsing in resources tab
+Styles for samples browser
*/
#codesample-wrapper {
@@ -2543,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;
@@ -4791,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 {
@@ -4839,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/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
index d54d371..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() {
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
+ | <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
+ | <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 3fed799..04c8d4b 100644
--- a/tools/droiddoc/templates-sdk/sample.cs
+++ b/tools/droiddoc/templates-sdk/sample.cs
@@ -27,7 +27,7 @@
<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 ?>
@@ -50,18 +50,37 @@
<?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>
+
+<?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,
@@ -69,6 +88,49 @@
<?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 8db15c4..98767b1 100644
--- a/tools/droiddoc/templates-sdk/sampleindex.cs
+++ b/tools/droiddoc/templates-sdk/sampleindex.cs
@@ -20,7 +20,9 @@
| Project<?cs else ?>Overview
| <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
<?cs /if ?>
-| <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+| <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 -->
@@ -78,6 +80,48 @@
so don't show src links (we dont have the pages!) ?>
<?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/edify_generator.py b/tools/releasetools/edify_generator.py
index 189672c..2c3b9e7 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -184,11 +184,6 @@
cmd = "delete(" + ",\0".join(['"%s"' % (i,) for i in file_list]) + ");"
self.script.append(self._WordWrap(cmd))
- def RenameFile(self, srcfile, tgtfile):
- """Moves a file from one location to another."""
- if self.info.get("update_rename_support", False):
- self.script.append('rename("%s", "%s");' % (srcfile, tgtfile))
-
def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
"""Apply binary patches (in *patchpairs) to the given srcfile to
produce tgtfile (which may be "-" to indicate overwriting the
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 2ef896f..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
@@ -108,31 +114,6 @@
symlink."""
return (info.external_attr >> 28) == 010
-def ClosestFileMatch(src, tgtfiles, existing):
- """Returns the closest file match between a source file and list
- of potential matches. The exact filename match is preferred,
- then the sha1 is searched for, and finally a file with the same
- basename is evaluated. Rename support in the updater-binary is
- required for the latter checks to be used."""
-
- result = tgtfiles.get("path:" + src.name)
- if result is not None:
- return result
-
- if not OPTIONS.target_info_dict.get("update_rename_support", False):
- return None
-
- if src.size < 1000:
- return None
-
- result = tgtfiles.get("sha1:" + src.sha1)
- if result is not None and existing.get(result.name) is None:
- return result
- result = tgtfiles.get("file:" + src.name.split("/")[-1])
- if result is not None and existing.get(result.name) is None:
- return result
- return None
-
class Item:
"""Items represent the metadata (user, group, mode) of files and
directories in the system image."""
@@ -429,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)
@@ -449,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)
@@ -470,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)
@@ -539,27 +571,11 @@
verbatim_targets = []
patch_list = []
diffs = []
- renames = {}
largest_source_size = 0
-
- matching_file_cache = {}
- for fn in source_data.keys():
- sf = source_data[fn]
- assert fn == sf.name
- matching_file_cache["path:" + fn] = sf
- # Only allow eligability for filename/sha matching
- # if there isn't a perfect path match.
- if target_data.get(sf.name) is None:
- matching_file_cache["file:" + fn.split("/")[-1]] = sf
- matching_file_cache["sha:" + sf.sha1] = sf
-
for fn in sorted(target_data.keys()):
tf = target_data[fn]
assert fn == tf.name
- sf = ClosestFileMatch(tf, matching_file_cache, renames)
- if sf is not None and sf.name != tf.name:
- print "File has moved from " + sf.name + " to " + tf.name
- renames[sf.name] = tf
+ sf = source_data.get(fn, None)
if sf is None or fn in OPTIONS.require_verbatim:
# This file should be included verbatim
@@ -572,7 +588,7 @@
# File is different; consider sending as a patch
diffs.append(common.Difference(tf, sf))
else:
- # Target file data identical to source (may still be renamed)
+ # Target file identical to source.
pass
common.ComputeDifferences(diffs)
@@ -584,8 +600,8 @@
tf.AddToZip(output_zip)
verbatim_targets.append((tf.name, tf.size))
else:
- common.ZipWriteStr(output_zip, "patch/" + sf.name + ".p", d)
- patch_list.append((sf.name, tf, sf, tf.size, common.sha1(d).hexdigest()))
+ common.ZipWriteStr(output_zip, "patch/" + tf.name + ".p", d)
+ patch_list.append((tf.name, tf, sf, tf.size, common.sha1(d).hexdigest()))
largest_source_size = max(largest_source_size, sf.size)
source_fp = GetBuildProp("ro.build.fingerprint", OPTIONS.source_info_dict)
@@ -601,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",
@@ -619,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()
@@ -656,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")
@@ -667,8 +737,7 @@
script.Print("Removing unneeded files...")
script.DeleteFiles(["/"+i[0] for i in verbatim_targets] +
["/"+i for i in sorted(source_data)
- if i not in target_data and
- i not in renames] +
+ if i not in target_data] +
["/system/recovery.img"])
script.ShowProgress(0.8, 0)
@@ -688,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
@@ -755,13 +825,6 @@
script.Print("Unpacking new recovery...")
script.UnpackPackageDir("recovery", "/system")
- if len(renames) > 0:
- script.Print("Renaming files...")
-
- for src in renames:
- print "Renaming " + src + " to " + renames[src].name
- script.RenameFile(src, renames[src].name)
-
script.Print("Symlinks and permissions...")
# Create all the symlinks that don't already exist, or point to
@@ -796,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)
@@ -822,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=",
@@ -836,6 +908,7 @@
"extra_script=",
"worker_threads=",
"aslr_mode=",
+ "two_step",
],
extra_option_handler=option_handler)