Merge "Add -Werror=date-time to target builds"
diff --git a/core/Makefile b/core/Makefile
index aee792a..3c1c84e 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -920,9 +920,9 @@
define build-recoveryimage-target
@echo ----- Making recovery image ------
$(hide) mkdir -p $(TARGET_RECOVERY_OUT)
- $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/tmp
+ $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
@echo Copying baseline ramdisk...
- $(hide) rsync -a --exclude=etc $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) # "cp -Rf" fails to overwrite broken symlinks on Mac.
+ $(hide) rsync -a --exclude=etc --exclude=sdcard $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) # "cp -Rf" fails to overwrite broken symlinks on Mac.
@echo Modifying ramdisk contents...
$(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
$(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
diff --git a/core/binary.mk b/core/binary.mk
index 4cb62b3..73d1d22 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -449,7 +449,6 @@
ifeq ($(LOCAL_CPP_EXTENSION),)
LOCAL_CPP_EXTENSION := .cpp
endif
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CPP_EXTENSION := $(LOCAL_CPP_EXTENSION)
# Certain modules like libdl have to have symbols resolved at runtime and blow
# up if --no-undefined is passed to the linker.
@@ -761,79 +760,57 @@
endif # $(aidl_src) non-empty
###########################################################
-## YACC: Compile .y and .yy files to .cpp and the to .o.
+## YACC: Compile .y/.yy files to .c/.cpp and then to .o.
###########################################################
y_yacc_sources := $(filter %.y,$(my_src_files))
-y_yacc_cpps := $(addprefix \
- $(intermediates)/,$(y_yacc_sources:.y=$(LOCAL_CPP_EXTENSION)))
+y_yacc_cs := $(addprefix \
+ $(intermediates)/,$(y_yacc_sources:.y=.c))
+ifneq ($(y_yacc_cs),)
+$(y_yacc_cs): $(intermediates)/%.c: \
+ $(TOPDIR)$(LOCAL_PATH)/%.y \
+ $(my_additional_dependencies)
+ $(call transform-y-to-c-or-cpp)
+
+my_generated_sources += $(y_yacc_cs)
+endif
yy_yacc_sources := $(filter %.yy,$(my_src_files))
yy_yacc_cpps := $(addprefix \
$(intermediates)/,$(yy_yacc_sources:.yy=$(LOCAL_CPP_EXTENSION)))
-
-yacc_cpps := $(y_yacc_cpps) $(yy_yacc_cpps)
-yacc_headers := $(yacc_cpps:$(LOCAL_CPP_EXTENSION)=.h)
-yacc_objects := $(yacc_cpps:$(LOCAL_CPP_EXTENSION)=.o)
-
-ifneq ($(strip $(y_yacc_cpps)),)
-$(y_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
- $(TOPDIR)$(LOCAL_PATH)/%.y \
- $(lex_cpps) $(my_additional_dependencies)
- $(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
-$(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
-endif
-
-ifneq ($(strip $(yy_yacc_cpps)),)
+ifneq ($(yy_yacc_cpps),)
$(yy_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
$(TOPDIR)$(LOCAL_PATH)/%.yy \
- $(lex_cpps) $(my_additional_dependencies)
- $(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
-$(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
-endif
+ $(my_additional_dependencies)
+ $(call transform-y-to-c-or-cpp)
-ifneq ($(strip $(yacc_cpps)),)
-$(yacc_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
-$(yacc_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
-$(yacc_objects): $(intermediates)/%.o: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
- $(transform-$(PRIVATE_HOST)cpp-to-o)
+my_generated_sources += $(yy_yacc_cpps)
endif
###########################################################
-## LEX: Compile .l and .ll files to .cpp and then to .o.
+## LEX: Compile .l/.ll files to .c/.cpp and then to .o.
###########################################################
l_lex_sources := $(filter %.l,$(my_src_files))
-l_lex_cpps := $(addprefix \
- $(intermediates)/,$(l_lex_sources:.l=$(LOCAL_CPP_EXTENSION)))
+l_lex_cs := $(addprefix \
+ $(intermediates)/,$(l_lex_sources:.l=.c))
+ifneq ($(l_lex_cs),)
+$(l_lex_cs): $(intermediates)/%.c: \
+ $(TOPDIR)$(LOCAL_PATH)/%.l
+ $(transform-l-to-c-or-cpp)
+
+my_generated_sources += $(l_lex_cs)
+endif
ll_lex_sources := $(filter %.ll,$(my_src_files))
ll_lex_cpps := $(addprefix \
$(intermediates)/,$(ll_lex_sources:.ll=$(LOCAL_CPP_EXTENSION)))
-
-lex_cpps := $(l_lex_cpps) $(ll_lex_cpps)
-lex_objects := $(lex_cpps:$(LOCAL_CPP_EXTENSION)=.o)
-
-ifneq ($(strip $(l_lex_cpps)),)
-$(l_lex_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
- $(TOPDIR)$(LOCAL_PATH)/%.l
- $(transform-l-to-cpp)
-endif
-
-ifneq ($(strip $(ll_lex_cpps)),)
+ifneq ($(ll_lex_cpps),)
$(ll_lex_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
$(TOPDIR)$(LOCAL_PATH)/%.ll
- $(transform-l-to-cpp)
-endif
+ $(transform-l-to-c-or-cpp)
-ifneq ($(strip $(lex_cpps)),)
-$(lex_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
-$(lex_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
-$(lex_objects): $(intermediates)/%.o: \
- $(intermediates)/%$(LOCAL_CPP_EXTENSION) \
- $(my_additional_dependencies) \
- $(yacc_headers)
- $(transform-$(PRIVATE_HOST)cpp-to-o)
+my_generated_sources += $(ll_lex_cpps)
endif
###########################################################
@@ -1138,8 +1115,6 @@
$(gen_c_objects) \
$(objc_objects) \
$(objcpp_objects) \
- $(yacc_objects) \
- $(lex_objects) \
$(proto_generated_objects) \
$(addprefix $(TOPDIR)$(LOCAL_PATH)/,$(LOCAL_PREBUILT_OBJ_FILES))
diff --git a/core/clang/arm.mk b/core/clang/arm.mk
index e66aa6c..4053bb2 100644
--- a/core/clang/arm.mk
+++ b/core/clang/arm.mk
@@ -29,8 +29,7 @@
-fno-partial-inlining \
-fno-strict-volatile-bitfields \
-fno-tree-copy-prop \
- -fno-tree-loop-optimize \
- -Wa,--noexecstack
+ -fno-tree-loop-optimize
define subst-clang-incompatible-arm-flags
$(subst -march=armv5te,-march=armv5t,\
diff --git a/core/clang/arm64.mk b/core/clang/arm64.mk
index ab395b3..cad7321 100644
--- a/core/clang/arm64.mk
+++ b/core/clang/arm64.mk
@@ -13,8 +13,7 @@
-frerun-cse-after-loop \
-frename-registers \
-fno-strict-volatile-bitfields \
- -fno-align-jumps \
- -Wa,--noexecstack
+ -fno-align-jumps
# We don't have any arm64 flags to substitute yet.
define subst-clang-incompatible-arm64-flags
diff --git a/core/combo/HOST_CROSS_windows-x86.mk b/core/combo/HOST_CROSS_windows-x86.mk
index 1ac1059..b6cbebc 100644
--- a/core/combo/HOST_CROSS_windows-x86.mk
+++ b/core/combo/HOST_CROSS_windows-x86.mk
@@ -32,8 +32,8 @@
$(combo_var_prefix)GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
# Use C99-compliant printf functions (%zd).
$(combo_var_prefix)GLOBAL_CFLAGS += -D__USE_MINGW_ANSI_STDIO=1
-# Admit to using >= Win2K. Both are needed because of <_mingw.h>.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D_WIN32_WINNT=0x0500 -DWINVER=0x0500
+# Admit to using >= Vista. Both are needed because of <_mingw.h>.
+$(combo_var_prefix)GLOBAL_CFLAGS += -D_WIN32_WINNT=0x0600 -DWINVER=0x0600
# Get 64-bit off_t and related functions.
$(combo_var_prefix)GLOBAL_CFLAGS += -D_FILE_OFFSET_BITS=64
diff --git a/core/config.mk b/core/config.mk
index da53c34..1af1995 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -529,8 +529,6 @@
# Tool to merge AndroidManifest.xmls
ANDROID_MANIFEST_MERGER := java -classpath prebuilts/devtools/tools/lib/manifest-merger.jar com.android.manifmerger.Main merge
-YACC_HEADER_SUFFIX:= .hpp
-
COLUMN:= column
# We may not have the right JAVA_HOME/PATH set up yet when this is run from envsetup.sh.
diff --git a/core/definitions.mk b/core/definitions.mk
index a6218cc..623f209 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -142,11 +142,27 @@
endef
###########################################################
+## Remove any makefiles that are being handled by soong
+###########################################################
+ifeq ($(USE_SOONG),true)
+define filter-soong-makefiles
+$(foreach mk,$(1),\
+ $(if $(wildcard $(patsubst %/Android.mk,%/Android.bp,$(mk))),\
+ $(info skipping $(mk) ...),\
+ $(mk)))
+endef
+else
+define filter-soong-makefiles
+$(1)
+endef
+endif
+
+###########################################################
## Retrieve a list of all makefiles immediately below some directory
###########################################################
define all-makefiles-under
-$(sort $(wildcard $(1)/*/Android.mk))
+$(sort $(call filter-soong-makefiles,$(wildcard $(1)/*/Android.mk)))
endef
###########################################################
@@ -157,8 +173,9 @@
# $(1): directory to search under
# Ignores $(1)/Android.mk
define first-makefiles-under
-$(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) \
- --mindepth=2 $(1) Android.mk)
+$(call filter-soong-makefiles,\
+ $(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) \
+ --mindepth=2 $(1) Android.mk))
endef
###########################################################
@@ -178,7 +195,8 @@
# $(1): List of directories to look for under this directory
define all-named-subdir-makefiles
-$(sort $(wildcard $(addsuffix /Android.mk, $(addprefix $(call my-dir)/,$(1)))))
+$(sort $(call filter-soong-makefiles,\
+ $(wildcard $(addsuffix /Android.mk, $(addprefix $(call my-dir)/,$(1))))))
endef
###########################################################
@@ -875,7 +893,7 @@
## Commands for running lex
###########################################################
-define transform-l-to-cpp
+define transform-l-to-c-or-cpp
@echo "Lex: $(PRIVATE_MODULE) <= $<"
@mkdir -p $(dir $@)
$(hide) $(LEX) -o$@ $<
@@ -884,20 +902,14 @@
###########################################################
## Commands for running yacc
##
-## Because the extension of c++ files can change, the
-## extension must be specified in $1.
-## E.g, "$(call transform-y-to-cpp,.cpp)"
###########################################################
-define transform-y-to-cpp
+define transform-y-to-c-or-cpp
@echo "Yacc: $(PRIVATE_MODULE) <= $<"
@mkdir -p $(dir $@)
-$(YACC) $(PRIVATE_YACCFLAGS) -o $@ $<
-touch $(@:$1=$(YACC_HEADER_SUFFIX))
-echo '#ifndef '$(@F:$1=_h) > $(@:$1=.h)
-echo '#define '$(@F:$1=_h) >> $(@:$1=.h)
-cat $(@:$1=$(YACC_HEADER_SUFFIX)) >> $(@:$1=.h)
-echo '#endif' >> $(@:$1=.h)
+$(YACC) $(PRIVATE_YACCFLAGS) \
+ --defines=$(basename $@).h \
+ -o $@ $<
endef
###########################################################
diff --git a/core/main.mk b/core/main.mk
index d2f8414..32b0b39 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -534,11 +534,12 @@
# --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)
+subdir_makefiles := $(SOONG_ANDROID_MK) $(call filter-soong-makefiles,$(subdir_makefiles))
endif
-$(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))
+$(foreach mk, $(subdir_makefiles),$(info including $(mk) ...)$(eval include $(mk)))
endif # dont_bother
diff --git a/core/ninja.mk b/core/ninja.mk
index 750aae5..2878514 100644
--- a/core/ninja.mk
+++ b/core/ninja.mk
@@ -1,6 +1,15 @@
+NINJA ?= prebuilts/ninja/$(HOST_PREBUILT_TAG)/ninja
+
+ifeq ($(USE_SOONG),true)
+USE_SOONG_FOR_KATI := true
+endif
+
+ifeq ($(USE_SOONG_FOR_KATI),true)
+include $(BUILD_SYSTEM)/soong.mk
+else
KATI ?= $(HOST_OUT_EXECUTABLES)/ckati
MAKEPARALLEL ?= $(HOST_OUT_EXECUTABLES)/makeparallel
-NINJA ?= prebuilts/ninja/$(HOST_PREBUILT_TAG)/ninja
+endif
KATI_OUTPUT_PATTERNS := $(OUT_DIR)/build%.ninja $(OUT_DIR)/ninja%.sh
@@ -119,8 +128,6 @@
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)
@@ -147,6 +154,7 @@
@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)/% --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)
+ifneq ($(USE_SOONG_FOR_KATI),true)
KATI_CXX := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_CFLAGS) $(CLANG_HOST_GLOBAL_CPPFLAGS)
KATI_LD := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_LDFLAGS)
# Build static ckati. Unfortunately Mac OS X doesn't officially support static exectuables.
@@ -168,6 +176,7 @@
MAKEPARALLEL_INTERMEDIATES_PATH := $(HOST_OUT_INTERMEDIATES)/EXECUTABLES/makeparallel_intermediates
MAKEPARALLEL_BIN_PATH := $(HOST_OUT_EXECUTABLES)
include build/tools/makeparallel/Makefile
+endif
.PHONY: FORCE
FORCE:
diff --git a/core/soong.mk b/core/soong.mk
index aab26de..646c68e 100644
--- a/core/soong.mk
+++ b/core/soong.mk
@@ -4,6 +4,9 @@
SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android.mk
SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
+SOONG_HOST_EXECUTABLES := $(SOONG_OUT_DIR)/host/$(HOST_PREBUILT_TAG)/bin
+KATI := $(SOONG_HOST_EXECUTABLES)/ckati
+MAKEPARALLEL := $(SOONG_HOST_EXECUTABLES)/makeparallel
ifeq (,$(filter /%,$(SOONG_OUT_DIR)))
SOONG_TOP_RELPATH := $(shell python -c "import os; print os.path.relpath('$(TOP)', '$(SOONG_OUT_DIR)')")
@@ -57,4 +60,7 @@
# 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)
+ $(hide) $(SOONG) $(KATI) $(MAKEPARALLEL) $(NINJA_ARGS)
+
+$(KATI): $(SOONG_ANDROID_MK)
+$(MAKEPARALLEL): $(SOONG_ANDROID_MK)
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 9b7b46a..d956124 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -23,6 +23,10 @@
LOCAL_IS_STATIC_JAVA_LIBRARY := true
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
# Hack to build static Java library with Android resource
# See bug 5714516
all_resources :=
@@ -59,10 +63,6 @@
LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
ifdef LOCAL_JACK_ENABLED
ifndef LOCAL_JACK_PROGUARD_FLAGS
LOCAL_JACK_PROGUARD_FLAGS := $(LOCAL_PROGUARD_FLAGS)
diff --git a/target/board/generic/sepolicy/property_contexts b/target/board/generic/sepolicy/property_contexts
index 152f0c8..142b062 100644
--- a/target/board/generic/sepolicy/property_contexts
+++ b/target/board/generic/sepolicy/property_contexts
@@ -1,5 +1,5 @@
qemu. u:object_r:qemu_prop:s0
-emu. u:object_r:qemu_prop:s0
-emulator. u:object_r:qemu_prop:s0
-radio.noril u:object_r:radio_noril_prop:s0
-opengles. u:object_r:opengles_prop:s0
+ro.emu. u:object_r:qemu_prop:s0
+ro.emulator. u:object_r:qemu_prop:s0
+ro.radio.noril u:object_r:radio_noril_prop:s0
+ro.opengles. u:object_r:opengles_prop:s0
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index e890fd2..c39ab2c 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -63,7 +63,6 @@
libfilterfw \
libkeystore \
libgatekeeper \
- libsqlite_jni \
libwilhelm \
logd \
make_ext4fs \
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
index 685ad31..3e3220b 100644
--- a/target/product/core_tiny.mk
+++ b/target/product/core_tiny.mk
@@ -61,7 +61,6 @@
libfilterfw \
libgatekeeper \
libkeystore \
- libsqlite_jni \
libwilhelm \
libdrmframework_jni \
libdrmframework \
diff --git a/tools/droiddoc/templates-sac/footer.cs b/tools/droiddoc/templates-sac/footer.cs
index e38374a..e43adb0 100644
--- a/tools/droiddoc/templates-sac/footer.cs
+++ b/tools/droiddoc/templates-sac/footer.cs
@@ -2,7 +2,7 @@
<style>.feedback { float: right !Important }</style>
<div class="feedback">
<a href="#" class="button" onclick=" try {
- userfeedback.api.startFeedback({'productId':'715571','authuser':'1'});return false;}catch(e){}">Feedback on Site</a>
+ userfeedback.api.startFeedback({'productId':'715571','authuser':'1'});return false;}catch(e){}">Site Feedback</a>
</div>
<div id="copyright">
<?cs call:custom_cc_copyright() ?>
diff --git a/tools/makeparallel/Android.bp b/tools/makeparallel/Android.bp
new file mode 100644
index 0000000..cb81817
--- /dev/null
+++ b/tools/makeparallel/Android.bp
@@ -0,0 +1,26 @@
+// Copyright 2016 Google Inc. All rights reserved
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary_host {
+ name: "makeparallel",
+ srcs: [
+ "makeparallel.cpp",
+ ],
+ cflags: ["-Wall", "-Werror"],
+ target: {
+ linux: {
+ host_ldlibs: ["-lrt", "-lpthread"],
+ },
+ },
+}
diff --git a/tools/makeparallel/makeparallel.cpp b/tools/makeparallel/makeparallel.cpp
index 576fe8d..cf125fa 100644
--- a/tools/makeparallel/makeparallel.cpp
+++ b/tools/makeparallel/makeparallel.cpp
@@ -343,7 +343,7 @@
// child
int ret = execvp(path, args.data());
if (ret < 0) {
- error(errno, errno, "exec failed");
+ error(errno, errno, "exec %s failed", path);
}
abort();
}
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 1a5b93d..1d338ee 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -613,12 +613,15 @@
def_cmd = stashes[idx][1]
assert (idx, sr) in def_cmd.stash_before
def_cmd.stash_before.remove((idx, sr))
- new_blocks += sr.size()
+ # Add up blocks that violates space limit and print total number to
+ # screen later.
+ new_blocks += cmd.tgt_ranges.size()
cmd.ConvertToNew()
- print(" Total %d blocks are packed as new blocks due to insufficient "
- "cache size." % (new_blocks,))
+ num_of_bytes = new_blocks * self.tgt.blocksize
+ print(" Total %d blocks (%d bytes) are packed as new blocks due to "
+ "insufficient cache size." % (new_blocks, num_of_bytes))
def ComputePatches(self, prefix):
print("Reticulating splines...")
@@ -987,29 +990,36 @@
too many blocks (greater than MAX_BLOCKS_PER_DIFF_TRANSFER), we split it
into smaller pieces by getting multiple Transfer()s.
- The downside is that after splitting, we can no longer use imgdiff but
- only bsdiff."""
-
- MAX_BLOCKS_PER_DIFF_TRANSFER = 1024
+ The downside is that after splitting, we may increase the package size
+ since the split pieces don't align well. According to our experiments,
+ 1/8 of the cache size as the per-piece limit appears to be optimal.
+ Compared to the fixed 1024-block limit, it reduces the overall package
+ size by 30% volantis, and 20% for angler and bullhead."""
# We care about diff transfers only.
if style != "diff" or not split:
Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
return
+ pieces = 0
+ cache_size = common.OPTIONS.cache_size
+ split_threshold = 0.125
+ max_blocks_per_transfer = int(cache_size * split_threshold /
+ self.tgt.blocksize)
+
# Change nothing for small files.
- if (tgt_ranges.size() <= MAX_BLOCKS_PER_DIFF_TRANSFER and
- src_ranges.size() <= MAX_BLOCKS_PER_DIFF_TRANSFER):
+ if (tgt_ranges.size() <= max_blocks_per_transfer and
+ src_ranges.size() <= max_blocks_per_transfer):
Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
return
- pieces = 0
- while (tgt_ranges.size() > MAX_BLOCKS_PER_DIFF_TRANSFER and
- src_ranges.size() > MAX_BLOCKS_PER_DIFF_TRANSFER):
+ while (tgt_ranges.size() > max_blocks_per_transfer and
+ src_ranges.size() > max_blocks_per_transfer):
tgt_split_name = "%s-%d" % (tgt_name, pieces)
src_split_name = "%s-%d" % (src_name, pieces)
- tgt_first = tgt_ranges.first(MAX_BLOCKS_PER_DIFF_TRANSFER)
- src_first = src_ranges.first(MAX_BLOCKS_PER_DIFF_TRANSFER)
+ tgt_first = tgt_ranges.first(max_blocks_per_transfer)
+ src_first = src_ranges.first(max_blocks_per_transfer)
+
Transfer(tgt_split_name, src_split_name, tgt_first, src_first, style,
by_id)
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 5afb8d1..06a8d7f 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -67,6 +67,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
@@ -116,14 +117,24 @@
private static final int USE_SHA256 = 2;
/**
+ * Minimum Android SDK API Level which accepts JAR signatures which use SHA-256. Older platform
+ * versions accept only SHA-1 signatures.
+ */
+ private static final int MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES = 18;
+
+ /**
* Return one of USE_SHA1 or USE_SHA256 according to the signature
* algorithm specified in the cert.
*/
- private static int getDigestAlgorithm(X509Certificate cert) {
+ private static int getDigestAlgorithm(X509Certificate cert, int minSdkVersion) {
String sigAlg = cert.getSigAlgName().toUpperCase(Locale.US);
- if ("SHA1WITHRSA".equals(sigAlg) ||
- "MD5WITHRSA".equals(sigAlg)) { // see "HISTORICAL NOTE" above.
- return USE_SHA1;
+ if ("SHA1WITHRSA".equals(sigAlg) || "MD5WITHRSA".equals(sigAlg)) {
+ // see "HISTORICAL NOTE" above.
+ if (minSdkVersion < MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES) {
+ return USE_SHA1;
+ } else {
+ return USE_SHA256;
+ }
} else if (sigAlg.startsWith("SHA256WITH")) {
return USE_SHA256;
} else {
@@ -133,10 +144,11 @@
}
/** Returns the expected signature algorithm for this key type. */
- private static String getSignatureAlgorithm(X509Certificate cert) {
+ private static String getSignatureAlgorithm(X509Certificate cert, int minSdkVersion) {
String keyType = cert.getPublicKey().getAlgorithm().toUpperCase(Locale.US);
if ("RSA".equalsIgnoreCase(keyType)) {
- if (getDigestAlgorithm(cert) == USE_SHA256) {
+ if ((minSdkVersion >= MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES)
+ || (getDigestAlgorithm(cert, minSdkVersion) == USE_SHA256)) {
return "SHA256withRSA";
} else {
return "SHA1withRSA";
@@ -309,10 +321,24 @@
Attributes attr = null;
if (input != null) attr = input.getAttributes(name);
attr = attr != null ? new Attributes(attr) : new Attributes();
+ // Remove any previously computed digests from this entry's attributes.
+ for (Iterator<Object> i = attr.keySet().iterator(); i.hasNext();) {
+ Object key = i.next();
+ if (!(key instanceof Attributes.Name)) {
+ continue;
+ }
+ String attributeNameLowerCase =
+ ((Attributes.Name) key).toString().toLowerCase(Locale.US);
+ if (attributeNameLowerCase.endsWith("-digest")) {
+ i.remove();
+ }
+ }
+ // Add SHA-1 digest if requested
if (md_sha1 != null) {
attr.putValue("SHA1-Digest",
new String(Base64.encode(md_sha1.digest()), "ASCII"));
}
+ // Add SHA-256 digest if requested
if (md_sha256 != null) {
attr.putValue("SHA-256-Digest",
new String(Base64.encode(md_sha256.digest()), "ASCII"));
@@ -418,7 +444,7 @@
print.flush();
Attributes sfAttr = new Attributes();
- sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest-Manifest",
+ sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest",
new String(Base64.encode(md.digest()), "ASCII"));
sf.getEntries().put(entry.getKey(), sfAttr);
}
@@ -438,7 +464,7 @@
/** Sign data and write the digital signature to 'out'. */
private static void writeSignatureBlock(
- CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey,
+ CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey, int minSdkVersion,
OutputStream out)
throws IOException,
CertificateEncodingException,
@@ -449,8 +475,9 @@
JcaCertStore certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
- ContentSigner signer = new JcaContentSignerBuilder(getSignatureAlgorithm(publicKey))
- .build(privateKey);
+ ContentSigner signer =
+ new JcaContentSignerBuilder(getSignatureAlgorithm(publicKey, minSdkVersion))
+ .build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder()
@@ -631,21 +658,23 @@
}
private static class CMSSigner implements CMSTypedData {
- private JarFile inputJar;
- private File publicKeyFile;
- private X509Certificate publicKey;
- private PrivateKey privateKey;
- private OutputStream outputStream;
+ private final JarFile inputJar;
+ private final File publicKeyFile;
+ private final X509Certificate publicKey;
+ private final PrivateKey privateKey;
+ private final int minSdkVersion;
+ private final OutputStream outputStream;
private final ASN1ObjectIdentifier type;
private WholeFileSignerOutputStream signer;
public CMSSigner(JarFile inputJar, File publicKeyFile,
- X509Certificate publicKey, PrivateKey privateKey,
+ X509Certificate publicKey, PrivateKey privateKey, int minSdkVersion,
OutputStream outputStream) {
this.inputJar = inputJar;
this.publicKeyFile = publicKeyFile;
this.publicKey = publicKey;
this.privateKey = privateKey;
+ this.minSdkVersion = minSdkVersion;
this.outputStream = outputStream;
this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
}
@@ -670,7 +699,7 @@
signer = new WholeFileSignerOutputStream(out, outputStream);
JarOutputStream outputJar = new JarOutputStream(signer);
- int hash = getDigestAlgorithm(publicKey);
+ int hash = getDigestAlgorithm(publicKey, minSdkVersion);
// Assume the certificate is valid for at least an hour.
long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
@@ -682,6 +711,7 @@
signFile(manifest,
new X509Certificate[]{ publicKey },
new PrivateKey[]{ privateKey },
+ minSdkVersion,
outputJar);
signer.notifyClosing();
@@ -698,7 +728,7 @@
CertificateEncodingException,
OperatorCreationException,
CMSException {
- SignApk.writeSignatureBlock(this, publicKey, privateKey, temp);
+ SignApk.writeSignatureBlock(this, publicKey, privateKey, minSdkVersion, temp);
}
public WholeFileSignerOutputStream getSigner() {
@@ -708,9 +738,10 @@
private static void signWholeFile(JarFile inputJar, File publicKeyFile,
X509Certificate publicKey, PrivateKey privateKey,
+ int minSdkVersion,
OutputStream outputStream) throws Exception {
CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile,
- publicKey, privateKey, outputStream);
+ publicKey, privateKey, minSdkVersion, outputStream);
ByteArrayOutputStream temp = new ByteArrayOutputStream();
@@ -776,6 +807,7 @@
private static void signFile(Manifest manifest,
X509Certificate[] publicKey, PrivateKey[] privateKey,
+ int minSdkVersion,
JarOutputStream outputJar)
throws Exception {
// Assume the certificate is valid for at least an hour.
@@ -795,7 +827,7 @@
je.setTime(timestamp);
outputJar.putNextEntry(je);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- writeSignatureFile(manifest, baos, getDigestAlgorithm(publicKey[k]));
+ writeSignatureFile(manifest, baos, getDigestAlgorithm(publicKey[k], minSdkVersion));
byte[] signedData = baos.toByteArray();
outputJar.write(signedData);
@@ -807,7 +839,7 @@
je.setTime(timestamp);
outputJar.putNextEntry(je);
writeSignatureBlock(new CMSProcessableByteArray(signedData),
- publicKey[k], privateKey[k], outputJar);
+ publicKey[k], privateKey[k], minSdkVersion, outputJar);
}
}
@@ -887,6 +919,7 @@
boolean signWholeFile = false;
String providerClass = null;
int alignment = 4;
+ int minSdkVersion = 0;
int argstart = 0;
while (argstart < args.length && args[argstart].startsWith("-")) {
@@ -902,6 +935,15 @@
} else if ("-a".equals(args[argstart])) {
alignment = Integer.parseInt(args[++argstart]);
++argstart;
+ } else if ("--min-sdk-version".equals(args[argstart])) {
+ String minSdkVersionString = args[++argstart];
+ try {
+ minSdkVersion = Integer.parseInt(minSdkVersionString);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "min-sdk-version must be a decimal number: " + minSdkVersionString);
+ }
+ ++argstart;
} else {
usage();
}
@@ -931,7 +973,7 @@
for (int i = 0; i < numKeys; ++i) {
int argNum = argstart + i*2;
publicKey[i] = readPublicKey(new File(args[argNum]));
- hashes |= getDigestAlgorithm(publicKey[i]);
+ hashes |= getDigestAlgorithm(publicKey[i], minSdkVersion);
}
} catch (IllegalArgumentException e) {
System.err.println(e);
@@ -955,7 +997,7 @@
if (signWholeFile) {
SignApk.signWholeFile(inputJar, firstPublicKeyFile,
- publicKey[0], privateKey[0], outputFile);
+ publicKey[0], privateKey[0], minSdkVersion, outputFile);
} else {
JarOutputStream outputJar = new JarOutputStream(outputFile);
@@ -969,7 +1011,7 @@
Manifest manifest = addDigestsToManifest(inputJar, hashes);
copyFiles(manifest, inputJar, outputJar, timestamp, alignment);
- signFile(manifest, publicKey, privateKey, outputJar);
+ signFile(manifest, publicKey, privateKey, minSdkVersion, outputJar);
outputJar.close();
}
} catch (Exception e) {