Bug 874132 - Second reland Part 3: Replace uses of apkbuilder with zip and custom debug signing tool. r=jmaher,mfinkle

This incorporates follow-ups including: rename the debug key; check if
key alias exists rather than just testing for keystore existence; set
$(AIDL).

Renaming the debug key works around an un-confirmed JDK bug in
jarsigner, where '-debug' and 'debug' compare the same.
This commit is contained in:
Nick Alexander 2013-06-20 11:50:28 -07:00
parent bd2a95a26c
commit e797d0b7b5
11 changed files with 157 additions and 106 deletions

View File

@ -13,6 +13,8 @@ dir-tests := $(DEPTH)/$(mobile-tests)
include $(DEPTH)/config/autoconf.mk
ANDROID_APK_NAME := robocop-debug
ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.6.jar
JAVAFILES = \
@ -81,9 +83,10 @@ GARBAGE += \
$(java-tests-dep) \
$(_JAVA_HARNESS) \
classes.dex \
robocop.ap_ \
robocop-debug-signed.apk \
robocop-debug-signed-unaligned.apk \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(robocop-deps) \
$(NULL)
@ -100,23 +103,28 @@ include $(topsrcdir)/config/android-common.mk
GENERATED_DIRS_tools = classes $(dir-tests)
libs:: robocop-debug-signed.apk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: robocop.ap_
classes.dex: $(ANDROID_APK_NAME).ap_
classes.dex: $(robocop-deps)
classes.dex: $(java-harness-dep)
classes.dex: $(java-tests-dep)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(java-tests-dep)
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) $(ANDROID_COMPT_LIB)
robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/*
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml $(TESTPATH)/assets/*
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
robocop-debug-signed-unaligned.apk: robocop.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z robocop.ap_ -f classes.dex
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
robocop-debug-signed.apk: robocop-debug-signed-unaligned.apk
$(ZIPALIGN) -f -v 4 $^ $@
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@
# PP_java-tests not fully usable here
# Intermediate step toward a library rule.

View File

@ -9,6 +9,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ANDROID_APK_NAME := sutAgentAndroid
JAVAFILES = \
AlertLooperThread.java \
ASMozStub.java \
@ -39,10 +41,10 @@ RES_FILES = \
GARBAGE += \
AndroidManifest.xml \
classes.dex \
sutAgentAndroid.apk \
sutAgentAndroid.ap_ \
sutAgentAndroid-unsigned-unaligned.apk \
sutAgentAndroid-unaligned.apk \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += network-libs
@ -56,23 +58,22 @@ include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: sutAgentAndroid.apk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes $(subst :, ,$(EXTRA_JARS))
sutAgentAndroid.ap_: $(srcdir)/AndroidManifest.xml
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
sutAgentAndroid-unsigned-unaligned.apk: sutAgentAndroid.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z sutAgentAndroid.ap_ -f classes.dex
sutAgentAndroid-unaligned.apk: sutAgentAndroid-unsigned-unaligned.apk
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
ifdef JARSIGNER
$(JARSIGNER) $@
endif
$(ZIP) -0 $@ classes.dex
sutAgentAndroid.apk: sutAgentAndroid-unaligned.apk
$(ZIPALIGN) -f -v 4 sutAgentAndroid-unaligned.apk $@
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -9,6 +9,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ANDROID_APK_NAME := FenCP
JAVAFILES = \
DirCursor.java \
FenCP.java \
@ -28,7 +30,10 @@ RES_FILES = \
GARBAGE += \
AndroidManifest.xml \
classes.dex \
FenCP.apk \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += network-libs
@ -40,23 +45,22 @@ include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: FenCP.apk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
FenCP.ap_: $(srcdir)/AndroidManifest.xml
$(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
FenCP-unsigned-unaligned.apk: FenCP.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z FenCP.ap_ -f classes.dex
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
FenCP-unaligned.apk: FenCP-unsigned-unaligned.apk
cp FenCP-unsigned-unaligned.apk $@
ifdef JARSIGNER
$(JARSIGNER) $@
endif
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
FenCP.apk: FenCP-unaligned.apk
$(ZIPALIGN) -f -v 4 FenCP-unaligned.apk $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -9,6 +9,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ANDROID_APK_NAME := FfxCP
JAVAFILES = \
DirCursor.java \
ffxcp.java \
@ -28,7 +30,10 @@ RES_FILES = \
GARBAGE += \
AndroidManifest.xml \
classes.dex \
FfxCP.apk \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += network-libs
@ -40,23 +45,22 @@ include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: FfxCP.apk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
FfxCP.ap_: $(srcdir)/AndroidManifest.xml
$(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
FfxCP-unsigned-unaligned.apk: FfxCP.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z FfxCP.ap_ -f classes.dex
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
FfxCP-unaligned.apk: FfxCP-unsigned-unaligned.apk
cp FfxCP-unsigned-unaligned.apk $@
ifdef JARSIGNER
$(JARSIGNER) $@
endif
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
FfxCP.apk: FfxCP-unaligned.apk
$(ZIPALIGN) -f -v 4 FfxCP-unaligned.apk $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -9,6 +9,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ANDROID_APK_NAME := Watcher
JAVAFILES = \
IWatcherService.java \
RedirOutputThread.java \
@ -32,7 +34,10 @@ RES_FILES = \
GARBAGE += \
AndroidManifest.xml \
classes.dex \
Watcher.apk \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += res classes network-libs
@ -44,29 +49,23 @@ include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: Watcher.apk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
Watcher.ap_: $(srcdir)/AndroidManifest.xml
$(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
Watcher-unsigned-unaligned.apk: Watcher.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z Watcher.ap_ -f classes.dex
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
Watcher-unaligned.apk: Watcher-unsigned-unaligned.apk
cp Watcher-unsigned-unaligned.apk $@
ifdef JARSIGNER
$(JARSIGNER) $@
endif
Watcher.apk: Watcher-unaligned.apk
$(ZIPALIGN) -f -v 4 Watcher-unaligned.apk $@
export::
$(NSINSTALL) -D res
@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/sutagent/android/watcher/res && tar -xf -)
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -14,12 +14,11 @@ endif
DX=$(ANDROID_BUILD_TOOLS)/dx
AAPT=$(ANDROID_BUILD_TOOLS)/aapt
APKBUILDER=$(ANDROID_SDK)/../../tools/apkbuilder
AIDL=$(ANDROID_BUILD_TOOLS)/aidl
ADB=$(ANDROID_PLATFORM_TOOLS)/adb
ZIPALIGN=$(ANDROID_SDK)/../../tools/zipalign
ifdef JARSIGNER
APKBUILDER_FLAGS += -u
endif
# DEBUG_JARSIGNER always debug signs.
DEBUG_JARSIGNER=$(PYTHON) $(call core_abspath,$(topsrcdir)/mobile/android/debug_sign_tool.py)
# For Android, this defaults to $(ANDROID_SDK)/android.jar
ifndef JAVA_BOOTCLASSPATH

View File

@ -1222,7 +1222,7 @@ jars:
$(NSINSTALL) -D jars
$(AIDL_AUTOGEN_FILES): %.java: %.aidl
$(ANDROID_PLATFORM_TOOLS)/aidl -I$(srcdir)/braille $<
$(AIDL) -I$(srcdir)/braille $<
CLASSES_WITH_JNI= \
org.mozilla.gecko.GeckoAppShell \

View File

@ -4,7 +4,7 @@
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
installer:
installer:
@$(MAKE) -C mobile/android/installer installer
package:
@ -14,6 +14,10 @@ fast-package:
@$(MAKE) package MOZ_FAST_PACKAGE=1
ifeq ($(OS_TARGET),Android)
# $(ADB) is defined in config/android-common.mk, but that file is not
# in scope when this file is read, so we define it locally.
ADB=$(ANDROID_PLATFORM_TOOLS)/adb
ifneq ($(MOZ_ANDROID_INSTALL_TARGET),)
ANDROID_SERIAL = $(MOZ_ANDROID_INSTALL_TARGET)
endif
@ -21,7 +25,7 @@ ifneq ($(ANDROID_SERIAL),)
export ANDROID_SERIAL
else
# Determine if there's more than one device connected
android_devices=$(filter device,$(shell $(ANDROID_PLATFORM_TOOLS)/adb devices))
android_devices=$(filter device,$(shell $(ADB) devices))
ifeq ($(android_devices),)
install::
@echo "No devices are connected. Connect a device or start an emulator."
@ -30,14 +34,14 @@ else
ifneq ($(android_devices),device)
install::
@echo "Multiple devices are connected. Define ANDROID_SERIAL to specify the install target."
$(ANDROID_PLATFORM_TOOLS)/adb devices
$(ADB) devices
@exit 1
endif
endif
endif
install::
$(ANDROID_PLATFORM_TOOLS)/adb install -r $(DIST)/$(PKG_PATH)$(PKG_BASENAME).apk
$(ADB) install -r $(DIST)/$(PKG_PATH)$(PKG_BASENAME).apk
else
@echo "Mobile can't be installed directly."
@exit 1

View File

@ -36,7 +36,7 @@ class DebugKeystore:
"""
def __init__(self, keystore):
self._keystore = os.path.abspath(os.path.expanduser(keystore))
self._alias = 'debug'
self._alias = 'androiddebugkey'
self.verbose = False
self.keytool = 'keytool'
self.jarsigner = 'jarsigner'
@ -49,14 +49,34 @@ class DebugKeystore:
def alias(self):
return self._alias
def _ensure_keystore(self):
if os.path.exists(self.keystore):
if self.verbose:
log.debug('Keystore exists at %s' % self.keystore)
def _check(self, args):
if self.verbose:
subprocess.check_call(args)
else:
self.create_keystore()
subprocess.check_output(args)
def create_keystore(self):
def keystore_contains_alias(self):
args = [ self.keytool,
'-list',
'-keystore', self.keystore,
'-storepass', 'android',
'-alias', self.alias,
]
if self.verbose:
args.append('-v')
contains = True
try:
self._check(args)
except subprocess.CalledProcessError as e:
contains = False
if self.verbose:
log.info('Keystore %s %s alias %s' %
(self.keystore,
'contains' if contains else 'does not contain',
self.alias))
return contains
def create_alias_in_keystore(self):
try:
path = os.path.dirname(self.keystore)
os.makedirs(path)
@ -65,8 +85,7 @@ class DebugKeystore:
raise
args = [ self.keytool,
'-genkey',
'-v',
'-genkeypair',
'-keystore', self.keystore,
'-storepass', 'android',
'-alias', self.alias,
@ -75,12 +94,16 @@ class DebugKeystore:
'-keyalg', 'RSA',
'-validity', '365',
]
subprocess.check_call(args)
if self.verbose:
log.info('Created keystore at %s' % self.keystore)
args.append('-v')
self._check(args)
if self.verbose:
log.info('Created alias %s in keystore %s' %
(self.alias, self.keystore))
def sign(self, apk):
self._ensure_keystore()
if not self.keystore_contains_alias():
self.create_alias_in_keystore()
args = [ self.jarsigner,
'-digestalg', 'SHA1',
@ -90,9 +113,12 @@ class DebugKeystore:
apk,
self.alias,
]
subprocess.check_call(args)
if self.verbose:
log.info('Signed %s with keystore at %s' % (apk, self.keystore))
args.append('-verbose')
self._check(args)
if self.verbose:
log.info('Signed %s with alias %s from keystore %s' %
(apk, self.alias, self.keystore))
def parse_args(argv):
@ -100,11 +126,11 @@ def parse_args(argv):
parser.add_argument('apks', nargs='+',
metavar='APK',
help='Android packages to be signed')
parser.add_argument('-q', '--quiet',
parser.add_argument('-v', '--verbose',
dest='verbose',
default=True,
action='store_false',
help='quiet output')
default=False,
action='store_true',
help='verbose output')
parser.add_argument('--keytool',
metavar='PATH',
default='keytool',
@ -135,9 +161,10 @@ def main():
if args.force:
try:
keystore.create_keystore()
keystore.create_alias_in_keystore()
except subprocess.CalledProcessError as e:
log.error('Failed to force-create keystore')
log.error('Failed to force-create alias %s in keystore %s' %
(keystore.alias, keystore.keystore))
log.error(e)
return 1

View File

@ -66,7 +66,7 @@ RUN_MOCHITEST_REMOTE = \
RUN_MOCHITEST_ROBOCOP = \
rm -f ./$@.log && \
$(PYTHON) _tests/testing/mochitest/runtestsremote.py \
--robocop-apk=$(DEPTH)/build/mobile/robocop/robocop-debug-signed.apk \
--robocop-apk=$(DEPTH)/build/mobile/robocop/robocop-debug.apk \
--robocop-ids=$(DEPTH)/mobile/android/base/fennec_ids.txt \
--robocop-ini=$(DEPTH)/build/mobile/robocop/robocop.ini \
--console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=$(DM_TRANS) \

View File

@ -247,10 +247,12 @@ ifeq ($(MOZ_PKG_FORMAT),APK)
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
include $(MOZILLA_DIR)/config/android-common.mk
# DEBUG_JARSIGNER is defined by android-common.mk and always debug
# signs. We want to release sign if possible.
ifdef MOZ_SIGN_CMD
JARSIGNER := $(MOZ_SIGN_CMD) -f jar
RELEASE_JARSIGNER := $(MOZ_SIGN_CMD) -f jar
else
JARSIGNER ?= echo
RELEASE_JARSIGNER := $(DEBUG_JARSIGNER)
endif
DIST_FILES =
@ -327,10 +329,12 @@ ifeq ($(MOZ_BUILD_APP),mobile/android)
UPLOAD_EXTRA_FILES += robocop.apk
UPLOAD_EXTRA_FILES += fennec_ids.txt
ROBOCOP_PATH = $(call core_abspath,$(_ABS_DIST)/../build/mobile/robocop)
# Robocop and Fennec need to be signed with the same key, which means
# release signing them both.
INNER_ROBOCOP_PACKAGE= \
$(NSINSTALL) $(GECKO_APP_AP_PATH)/fennec_ids.txt $(_ABS_DIST) && \
cp $(ROBOCOP_PATH)/robocop-debug-signed-unaligned.apk $(_ABS_DIST)/robocop-unaligned.apk && \
$(JARSIGNER) $(_ABS_DIST)/robocop-unaligned.apk && \
cp $(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk $(_ABS_DIST)/robocop-unaligned.apk && \
$(RELEASE_JARSIGNER) $(_ABS_DIST)/robocop-unaligned.apk && \
$(ZIPALIGN) -f -v 4 $(_ABS_DIST)/robocop-unaligned.apk $(_ABS_DIST)/robocop.apk
endif
else
@ -370,9 +374,10 @@ INNER_MAKE_PACKAGE = \
$(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ $(DIST_FILES) -x $(NON_DIST_FILES) $(SZIP_LIBRARIES) && \
$(ZIP) -0 $(_ABS_DIST)/gecko.ap_ $(OMNIJAR_NAME)) && \
rm -f $(_ABS_DIST)/gecko.apk && \
$(APKBUILDER) $(_ABS_DIST)/gecko.apk -v $(APKBUILDER_FLAGS) -z $(_ABS_DIST)/gecko.ap_ -f $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \
cp $(_ABS_DIST)/gecko.ap_ $(_ABS_DIST)/gecko.apk && \
$(ZIP) -j0 $(_ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \
cp $(_ABS_DIST)/gecko.apk $(_ABS_DIST)/gecko-unsigned-unaligned.apk && \
$(JARSIGNER) $(_ABS_DIST)/gecko.apk && \
$(RELEASE_JARSIGNER) $(_ABS_DIST)/gecko.apk && \
$(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) && \
$(INNER_ROBOCOP_PACKAGE)