diff --git a/build-android-with-native.py b/build-android-with-native.py index e5743ee9f..2ad5557ab 100755 --- a/build-android-with-native.py +++ b/build-android-with-native.py @@ -11,6 +11,7 @@ import re import sys import copy import shutil +from xml.dom.minidom import parse from subprocess import call, check_output # target platform to compile for @@ -18,7 +19,13 @@ from subprocess import call, check_output # arm-linux-androideabi, mipsel-linux-android, x86, llvm ALL_ARCHS = ['arm-linux-androideabi', 'mipsel-linux-android', 'x86'] -PACKAGE = 'org.kiwix.kiwixmobile' + +def find_package(): + d = parse('AndroidManifest.xml') + return [e.getAttribute('package').strip() + for e in d.getElementsByTagName('manifest')][-1] + +PACKAGE = find_package() USAGE = '''Usage: {arg0} [--option] @@ -38,9 +45,7 @@ USAGE = '''Usage: {arg0} [--option] --on=ARCH Disable steps on all archs and cherry pick the ones wanted. Multiple --on=ARCH can be specified. - ARCH in 'armeabi', 'mips', 'x86'. - - --package=org.kiwix.kiwixmobile ''' + ARCH in 'armeabi', 'mips', 'x86'. ''' def init_with_args(args): @@ -83,13 +88,6 @@ def init_with_args(args): # recreate options list from other items options = [v for v in doptions.values() if not v.startswith('--on=')] - # do we have an --package= flag? - if '--package=' in u' '.join(args): - for option in options: - if option.startswith('--package'): - global PACKAGE - PACKAGE = option.split('=', 1)[-1] - if len(options): # we received options. # consider we only want the specified steps @@ -548,6 +546,8 @@ for arch in ARCHS: if LOCALES_TXT: + os.chdir(curdir) + # Get the path of the res folder res_path = os.path.join(curdir, 'res') @@ -568,18 +568,32 @@ if LOCALES_TXT: if COMPILE_APK: + os.chdir(curdir) + # Compile java and build APK - syscall('rm -f build/outputs/apk/*.apk', shell=True) + syscall('rm -f build/outputs/apk/{}-*.apk'.format(PACKAGE), shell=True) syscall('./gradlew build --stacktrace') + folder_name = os.path.split(curdir)[-1] + # Check that the step went well - if not os.path.exists(os.path.join('build', 'outputs', 'apk', - 'android-debug-unaligned.apk')): - failed_on_step("The android-debug-unaligned.apk package " - "has not been created and is not present.") + if not os.path.exists( + os.path.join('build', 'outputs', 'apk', + '{}-debug-unaligned.apk'.format(folder_name))): + failed_on_step("The {}-debug-unaligned.apk package " + "has not been created and is not present." + .format(folder_name)) + + # rename APKs for better listing + for variant in ('debug', 'debug-unaligned', 'release-unsigned'): + shutil.move(os.path.join('build', 'outputs', 'apk', + "{}-{}.apk".format(folder_name, variant)), + os.path.join('build', 'outputs', 'apk', + "{}-{}.apk".format(PACKAGE, variant))) if CLEAN: + os.chdir(curdir) # remove everything from build folder expect the APKs syscall('rm -rf build/generated build/intermediates build/native-libs ' 'build/reports build/test-results build/tmp build/outputs/logs ' diff --git a/create-signed-android-release.sh b/create-signed-android-release.sh index 20a065694..c8e15116b 100755 --- a/create-signed-android-release.sh +++ b/create-signed-android-release.sh @@ -1,12 +1,16 @@ #!/bin/bash +function usage { + echo "Usage: $0 kiwix-android.keystore [PACKAGE] [APP_NAME] [APP_VERSION]" + echo "You must specify the path of the certificate keystore." + exit 1 +} + if [ -f "$1" ]; then CERTIFICATE=$1 else - echo "Usage: $0 Kiwix-android.keystore" - echo "You must specify the path of the certificate keystore." - exit 1 + usage fi function die { @@ -17,11 +21,31 @@ function die { exit 1 } +# default values are guessed from repo (AndroidManifest and res/values/branding) +APP_NAME=`python -c "from xml.dom.minidom import parse; d=parse('res/values/branding.xml'); print([e.childNodes[0].data.strip() for e in d.getElementsByTagName('string') if e.getAttribute('name') == 'app_name'][-1])"` +PACKAGE=`python -c "from xml.dom.minidom import parse; d=parse('AndroidManifest.xml'); print([e.getAttribute('package').strip() for e in d.getElementsByTagName('manifest')][-1])"` +APP_VERSION=`python -c "from xml.dom.minidom import parse; d=parse('AndroidManifest.xml'); print([e.getAttribute('android:versionName').strip() for e in d.getElementsByTagName('manifest')][-1])"` + +if [ "x$2" != "x" ]; + then + PACKAGE=$2 +fi + +if [ "x$3" != "x" ]; + then + APP_NAME=$3 +fi + +if [ "x$4" != "x" ]; + then + APP_VERSION=$4 +fi + ../src/dependencies/android-sdk/tools/android update project -p . -n Kiwix -t android-21 -jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore $CERTIFICATE build/outputs/apk/android-release-unsigned.apk kiwix || die "Error signing the package." -jarsigner -verify build/outputs/apk/android-release-unsigned.apk || die "The package is not properly signed." -../src/dependencies/android-sdk/build-tools/21.1.2/zipalign -f -v 4 build/outputs/apk/android-release-unsigned.apk kiwix-android.apk || die "Could not zipalign the signed package. Please check." +jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore $CERTIFICATE build/outputs/apk/${PACKAGE}-release-unsigned.apk kiwix || die "Error signing the package." +jarsigner -verify build/outputs/apk/${PACKAGE}-release-unsigned.apk || die "The package is not properly signed." +../src/dependencies/android-sdk/build-tools/21.1.2/zipalign -f -v 4 build/outputs/apk/${PACKAGE}-release-unsigned.apk "${APP_NAME}-${APP_VERSION}.apk" || die "Could not zipalign the signed package. Please check." echo "[SUCCESS] Your signed release package is ready:" -ls -lh kiwix-android.apk +ls -lh "${APP_NAME}-${APP_VERSION}.apk" diff --git a/gen-custom-android-build.py b/gen-custom-android-build.py index f407d379b..44fda86c8 100755 --- a/gen-custom-android-build.py +++ b/gen-custom-android-build.py @@ -330,10 +330,17 @@ def main(args): '--package={}' .format(jsdata.get('package'))) # --apk --clean') - # copy APK somewhere + # move generated APK to satisfy other scripts + for variant in ('debug', 'debug-unaligned', 'release-unsigned'): + shutil.move(os.path.join(ANDROID_PATH, 'build', 'outputs', 'apk', + "{}-{}.apk" + .format(jsdata.get('package'), variant)), + os.path.join(CURRENT_PATH, 'build', 'outputs', 'apk', + "{}-{}.apk" + .format(jsdata.get('package'), variant))) # delete temp folder - # shutil.rmtree(ANDROID_PATH) + shutil.rmtree(ANDROID_PATH) if __name__ == '__main__': main(sys.argv) diff --git a/install-kiwix-on-device.sh b/install-kiwix-on-device.sh index 1cbd2dcdd..d23da3102 100755 --- a/install-kiwix-on-device.sh +++ b/install-kiwix-on-device.sh @@ -1,8 +1,17 @@ #!/bin/bash -if [ -f build/outputs/apk/android-debug-unaligned.apk ] + +# default value is guessed from repo (AndroidManifest) +PACKAGE=`python -c "from xml.dom.minidom import parse; d=parse('AndroidManifest.xml'); print([e.getAttribute('package').strip() for e in d.getElementsByTagName('manifest')][-1])"` + +if [ "x$1" != "x" ]; + then + PACKAGE=$1 +fi + +if [ -f build/outputs/apk/${PACKAGE}-debug-unaligned.apk ] then - ../src/dependencies/android-sdk/platform-tools/adb uninstall org.kiwix.kiwixmobile ; - ../src/dependencies/android-sdk/platform-tools/adb install build/outputs/apk/android-debug-unaligned.apk + ../src/dependencies/android-sdk/platform-tools/adb uninstall ${PACKAGE} ; + ../src/dependencies/android-sdk/platform-tools/adb install build/outputs/apk/${PACKAGE}-debug-unaligned.apk else - echo "No APK file available!" -fi \ No newline at end of file + echo "No APK file available for package ${PACKAGE} !" +fi