diff --git a/buildserver/provision-apt-get-install b/buildserver/provision-apt-get-install index de8dd3fb..5ef8d1b3 100644 --- a/buildserver/provision-apt-get-install +++ b/buildserver/provision-apt-get-install @@ -49,6 +49,7 @@ apt-get upgrade --download-only apt-get upgrade packages=" + androguard/stretch-backports ant asn1c ant-contrib @@ -99,6 +100,7 @@ packages=" python-magic python-pip python-setuptools + python3-asn1crypto/stretch-backports python3-defusedxml python3-git python3-gitdb diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ee093778..df9ffe25 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -114,7 +114,7 @@ default_config = { 'r16b': None, }, 'cachedir': os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver'), - 'build_tools': MINIMUM_AAPT_BUILD_TOOLS_VERSION, + 'build_tools': MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION, 'java_paths': None, 'scan_binary': False, 'ant': "ant", @@ -423,7 +423,8 @@ def find_apksigner(): Returns the best version of apksigner following this algorithm: * use config['apksigner'] if set * try to find apksigner in path - * find apksigner in build-tools starting from newest installed going down to MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION + * find apksigner in build-tools starting from newest installed + going down to MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION :return: path to apksigner or None if no version is found """ if set_command_in_config('apksigner'): @@ -434,7 +435,7 @@ def find_apksigner(): for f in sorted(os.listdir(build_tools_path), reverse=True): if not os.path.isdir(os.path.join(build_tools_path, f)): continue - if LooseVersion(f) < LooseVersion(MINIMUM_AAPT_BUILD_TOOLS_VERSION): + if LooseVersion(f) < LooseVersion(MINIMUM_APKSIGNER_BUILD_TOOLS_VERSION): return None if os.path.exists(os.path.join(build_tools_path, f, 'apksigner')): apksigner = os.path.join(build_tools_path, f, 'apksigner') @@ -507,6 +508,7 @@ def test_aapt_version(aapt): def test_sdk_exists(thisconfig): if 'sdk_path' not in thisconfig: + # TODO convert this to apksigner once it is required if 'aapt' in thisconfig and os.path.isfile(thisconfig['aapt']): test_aapt_version(thisconfig['aapt']) return True @@ -2388,19 +2390,15 @@ def ensure_final_value(packageName, arsc, value): return '' -def is_apk_and_debuggable_aapt(apkfile): - p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'], - output=False) - if p.returncode != 0: - raise FDroidException(_("Failed to get APK manifest information")) - for line in p.output.splitlines(): - if 'android:debuggable' in line and not line.endswith('0x0'): - return True - return False +def is_apk_and_debuggable(apkfile): + """Returns True if the given file is an APK and is debuggable + Parse only from the APK. -def is_apk_and_debuggable_androguard(apkfile): - """Parse only from the APK""" + :param apkfile: full path to the apk to check""" + + if get_file_extension(apkfile) != 'apk': + return False from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG with ZipFile(apkfile) as apk: with apk.open('AndroidManifest.xml') as manifest: @@ -2422,20 +2420,6 @@ def is_apk_and_debuggable_androguard(apkfile): return False -def is_apk_and_debuggable(apkfile): - """Returns True if the given file is an APK and is debuggable - - :param apkfile: full path to the apk to check""" - - if get_file_extension(apkfile) != 'apk': - return False - - if use_androguard(): - return is_apk_and_debuggable_androguard(apkfile) - else: - return is_apk_and_debuggable_aapt(apkfile) - - def get_apk_id(apkfile): """Extract identification information from APK. @@ -2448,15 +2432,12 @@ def get_apk_id(apkfile): :returns: triplet (appid, version code, version name) """ - if use_androguard(): - try: - return get_apk_id_androguard(apkfile) - except zipfile.BadZipFile as e: - logging.error(apkfile + ': ' + str(e)) - if 'aapt' in config: - return get_apk_id_aapt(apkfile) - else: - return get_apk_id_aapt(apkfile) + try: + return get_apk_id_androguard(apkfile) + except zipfile.BadZipFile as e: + logging.error(apkfile + ': ' + str(e)) + if 'aapt' in config: + return get_apk_id_aapt(apkfile) def get_apk_id_androguard(apkfile): diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 20596130..f53057a0 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -75,46 +75,44 @@ def main(): # in ANDROID_HOME if that exists, otherwise None if options.android_home is not None: test_config['sdk_path'] = options.android_home - elif common.use_androguard(): - pass elif not common.test_sdk_exists(test_config): - if os.path.isfile('/usr/bin/aapt'): - # remove sdk_path and build_tools, they are not required - test_config.pop('sdk_path', None) - test_config.pop('build_tools', None) - # make sure at least aapt is found, since this can't do anything without it - test_config['aapt'] = common.find_sdk_tools_cmd('aapt') + # if neither --android-home nor the default sdk_path + # exist, prompt the user using platform-specific default + # and if the user leaves it blank, ignore and move on. + default_sdk_path = '' + if sys.platform == 'win32' or sys.platform == 'cygwin': + p = os.path.join(os.getenv('USERPROFILE'), + 'AppData', 'Local', 'Android', 'android-sdk') + elif sys.platform == 'darwin': + # on OSX, Homebrew is common and has an easy path to detect + p = '/usr/local/opt/android-sdk' + elif os.path.isdir('/usr/lib/android-sdk'): + # if the Debian packages are installed, suggest them + p = '/usr/lib/android-sdk' else: - # if neither --android-home nor the default sdk_path - # exist, prompt the user using platform-specific default - default_sdk_path = '/opt/android-sdk' - if sys.platform == 'win32' or sys.platform == 'cygwin': - p = os.path.join(os.getenv('USERPROFILE'), - 'AppData', 'Local', 'Android', 'android-sdk') - elif sys.platform == 'darwin': - # on OSX, Homebrew is common and has an easy path to detect - p = '/usr/local/opt/android-sdk' - else: - # if the Debian packages are installed, suggest them - p = '/usr/lib/android-sdk' - if os.path.exists(p): - default_sdk_path = p + p = '/opt/android-sdk' + if os.path.exists(p): + default_sdk_path = p - while not options.no_prompt: - try: - s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) - except KeyboardInterrupt: - print('') - sys.exit(1) - if re.match(r'^\s*$', s) is not None: - test_config['sdk_path'] = default_sdk_path - else: - test_config['sdk_path'] = s - if common.test_sdk_exists(test_config): - break - if (options.android_home is not None or not common.use_androguard()) \ - and not common.test_sdk_exists(test_config): - raise FDroidException("Android SDK not found.") + while not options.no_prompt: + try: + s = input(_('Enter the path to the Android SDK (%s) here:\n> ') % default_sdk_path) + except KeyboardInterrupt: + print('') + sys.exit(1) + if re.match(r'^\s*$', s) is not None: + test_config['sdk_path'] = default_sdk_path + else: + test_config['sdk_path'] = s + if not default_sdk_path: + del(test_config['sdk_path']) + break + if common.test_sdk_exists(test_config): + break + + if test_config.get('sdk_path') and not common.test_sdk_exists(test_config): + raise FDroidException(_("Android SDK not found at {path}!") + .format(path=test_config['sdk_path'])) if not os.path.exists('config.py'): # 'metadata' and 'tmp' are created in fdroid @@ -134,34 +132,13 @@ def main(): logging.info('Try running `fdroid init` in an empty directory.') raise FDroidException('Repository already exists.') - if common.use_androguard(): - pass - elif 'aapt' not in test_config or not os.path.isfile(test_config['aapt']): - # try to find a working aapt, in all the recent possible paths - build_tools = os.path.join(test_config['sdk_path'], 'build-tools') - aaptdirs = [] - aaptdirs.append(os.path.join(build_tools, test_config['build_tools'])) - aaptdirs.append(build_tools) - for f in os.listdir(build_tools): - if os.path.isdir(os.path.join(build_tools, f)): - aaptdirs.append(os.path.join(build_tools, f)) - for d in sorted(aaptdirs, reverse=True): - if os.path.isfile(os.path.join(d, 'aapt')): - aapt = os.path.join(d, 'aapt') - break - if aapt and os.path.isfile(aapt): - dirname = os.path.basename(os.path.dirname(aapt)) - if dirname == 'build-tools': - # this is the old layout, before versioned build-tools - test_config['build_tools'] = '' - else: - test_config['build_tools'] = dirname - common.write_to_config(test_config, 'build_tools') - common.ensure_build_tools_exists(test_config) - # now that we have a local config.py, read configuration... config = common.read_config(options) + # enable apksigner by default so v2/v3 APK signatures validate + if common.find_apksigner() is not None: + test_config['apksigner'] = common.find_apksigner() + # the NDK is optional and there may be multiple versions of it, so it's # left for the user to configure diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 9a2f80d4..a2512db6 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -49,7 +49,6 @@ from . import _ from . import common from . import index from . import metadata -from .common import SdkToolsPopen from .exception import BuildException, FDroidException from PIL import Image, PngImagePlugin @@ -1350,10 +1349,7 @@ def scan_apk(apk_file): 'antiFeatures': set(), } - if common.use_androguard(): - scan_apk_androguard(apk, apk_file) - else: - scan_apk_aapt(apk, apk_file) + scan_apk_androguard(apk, apk_file) if not common.is_valid_package_name(apk['packageName']): raise BuildException(_("{appid} from {path} is not a valid Java Package Name!") @@ -1412,83 +1408,6 @@ def _get_apk_icons_src(apkfile, icon_name): return icons_src -def scan_apk_aapt(apk, apkfile): - p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False) - if p.returncode != 0: - if options.delete_unknown: - if os.path.exists(apkfile): - logging.error(_("Failed to get apk information, deleting {path}").format(path=apkfile)) - os.remove(apkfile) - else: - logging.error("Could not find {0} to remove it".format(apkfile)) - else: - logging.error(_("Failed to get apk information, skipping {path}").format(path=apkfile)) - raise BuildException(_("Invalid APK")) - icon_name = None - for line in p.output.splitlines(): - if line.startswith("package:"): - try: - apk['packageName'] = re.match(APK_NAME_PAT, line).group(1) - apk['versionCode'] = int(re.match(APK_VERCODE_PAT, line).group(1)) - apk['versionName'] = re.match(APK_VERNAME_PAT, line).group(1) - except Exception as e: - raise FDroidException("Package matching failed: " + str(e) + "\nLine was: " + line) - elif line.startswith("application:"): - m = re.match(APK_LABEL_ICON_PAT, line) - if m: - apk['name'] = m.group(1) - icon_name = os.path.splitext(os.path.basename(m.group(2)))[0] - elif not apk.get('name') and line.startswith("launchable-activity:"): - # Only use launchable-activity as fallback to application - apk['name'] = re.match(APK_LABEL_ICON_PAT, line).group(1) - elif line.startswith("sdkVersion:"): - m = re.match(APK_SDK_VERSION_PAT, line) - if m is None: - logging.error(line.replace('sdkVersion:', '') - + ' is not a valid minSdkVersion!') - else: - apk['minSdkVersion'] = int(m.group(1)) - elif line.startswith("targetSdkVersion:"): - m = re.match(APK_SDK_VERSION_PAT, line) - if m is None: - logging.error(line.replace('targetSdkVersion:', '') - + ' is not a valid targetSdkVersion!') - else: - apk['targetSdkVersion'] = int(m.group(1)) - elif line.startswith("maxSdkVersion:"): - apk['maxSdkVersion'] = int(re.match(APK_SDK_VERSION_PAT, line).group(1)) - elif line.startswith("native-code:"): - apk['nativecode'] = [] - for arch in line[13:].split(' '): - apk['nativecode'].append(arch[1:-1]) - elif line.startswith('uses-permission:'): - perm_match = re.match(APK_PERMISSION_PAT, line).groups() - permission = UsesPermission( - perm_match[0], # name - None if perm_match[1] is None else int(perm_match[1]), # maxSdkVersion - ) - apk['uses-permission'].append(permission) - - elif line.startswith('uses-permission-sdk-23:'): - perm_match = re.match(APK_PERMISSION_PAT, line).groups() - permission_sdk_23 = UsesPermissionSdk23( - perm_match[0], # name - None if perm_match[1] is None else int(perm_match[1]), # maxSdkVersion - ) - apk['uses-permission-sdk-23'].append(permission_sdk_23) - - elif line.startswith('uses-feature:'): - feature = re.match(APK_FEATURE_PAT, line).group(1) - # Filter out this, it's only added with the latest SDK tools and - # causes problems for lots of apps. - if feature != "android.hardware.screen.portrait" \ - and feature != "android.hardware.screen.landscape": - if feature.startswith("android.feature."): - feature = feature[16:] - apk['features'].add(feature) - apk['icons_src'] = _get_apk_icons_src(apkfile, icon_name) - - def _sanitize_sdk_version(value): """Sanitize the raw values from androguard to handle bad values @@ -1529,8 +1448,6 @@ def scan_apk_androguard(apk, apkfile): logging.error(_("Failed to get apk information, skipping {path}") .format(path=apkfile)) raise BuildException(_("Invalid APK")) - except ImportError: - raise FDroidException("androguard library is not installed and aapt not present") except FileNotFoundError: logging.error(_("Could not open apk file for analysis")) raise BuildException(_("Invalid APK")) diff --git a/tests/build.TestCase b/tests/build.TestCase index decae7ab..ea1af963 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -43,13 +43,6 @@ class BuildTest(unittest.TestCase): print('no build-tools found: ' + build_tools) return False - def _find_all(self): - for cmd in ('aapt', 'adb', 'android', 'zipalign'): - path = fdroidserver.common.find_sdk_tools_cmd(cmd) - if path is not None: - self.assertTrue(os.path.exists(path)) - self.assertTrue(os.path.isfile(path)) - def setUp(self): logging.basicConfig(level=logging.DEBUG) self.basedir = os.path.join(localmodule, 'tests') diff --git a/tests/common.TestCase b/tests/common.TestCase index ca06de8b..ff7befb1 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -78,7 +78,7 @@ class CommonTest(unittest.TestCase): for f in sorted(os.listdir(build_tools), reverse=True): versioned = os.path.join(build_tools, f) if os.path.isdir(versioned) \ - and os.path.isfile(os.path.join(versioned, 'aapt')): + and os.path.isfile(os.path.join(versioned, 'apksigner')): fdroidserver.common.config['build_tools'] = versioned break return True @@ -148,11 +148,6 @@ class CommonTest(unittest.TestCase): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config - self._set_build_tools() - try: - config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - pass # aapt is not required if androguard is present # these are set debuggable testfiles = [] @@ -160,15 +155,8 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'urzip-badsig.apk')) testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk')) for apkfile in testfiles: - debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) - self.assertTrue(debuggable, + self.assertTrue(fdroidserver.common.is_apk_and_debuggable(apkfile), "debuggable APK state was not properly parsed!") - if 'aapt' in config: - self.assertTrue(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), - 'aapt parsing missed !') - if fdroidserver.common.use_androguard(): - self.assertTrue(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), - 'androguard missed !') # these are set NOT debuggable testfiles = [] @@ -176,15 +164,8 @@ class CommonTest(unittest.TestCase): testfiles.append(os.path.join(self.basedir, 'urzip-release-unsigned.apk')) testfiles.append(os.path.join(self.basedir, 'v2.only.sig_2.apk')) for apkfile in testfiles: - debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) - self.assertFalse(debuggable, + self.assertFalse(fdroidserver.common.is_apk_and_debuggable(apkfile), "debuggable APK state was not properly parsed!") - if 'aapt' in config: - self.assertFalse(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), - 'aapt parsing missed !') - if fdroidserver.common.use_androguard(): - self.assertFalse(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), - 'androguard missed !') VALID_STRICT_PACKAGE_NAMES = [ "An.stop", @@ -765,16 +746,15 @@ class CommonTest(unittest.TestCase): ('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk', 'info.guardianproject.urzip', '100', '0.1'), ] for apkfilename, appid, versionCode, versionName in testcases: + a, vc, vn = fdroidserver.common.get_apk_id(apkfilename) + self.assertEqual(appid, a, 'androguard appid parsing failed for ' + apkfilename) + self.assertEqual(versionName, vn, 'androguard versionName parsing failed for ' + apkfilename) + self.assertEqual(versionCode, vc, 'androguard versionCode parsing failed for ' + apkfilename) if 'aapt' in config: a, vc, vn = fdroidserver.common.get_apk_id_aapt(apkfilename) self.assertEqual(appid, a, 'aapt appid parsing failed for ' + apkfilename) self.assertEqual(versionCode, vc, 'aapt versionCode parsing failed for ' + apkfilename) self.assertEqual(versionName, vn, 'aapt versionName parsing failed for ' + apkfilename) - if fdroidserver.common.use_androguard(): - a, vc, vn = fdroidserver.common.get_apk_id(apkfilename) - self.assertEqual(appid, a, 'androguard appid parsing failed for ' + apkfilename) - self.assertEqual(versionName, vn, 'androguard versionName parsing failed for ' + apkfilename) - self.assertEqual(versionCode, vc, 'androguard versionCode parsing failed for ' + apkfilename) with self.assertRaises(FDroidException): fdroidserver.common.get_apk_id('nope') diff --git a/tests/metadata/apk/info.guardianproject.urzip.yaml b/tests/metadata/apk/info.guardianproject.urzip.yaml index f2e17651..4632c314 100644 --- a/tests/metadata/apk/info.guardianproject.urzip.yaml +++ b/tests/metadata/apk/info.guardianproject.urzip.yaml @@ -10,6 +10,7 @@ icons_src: '-1': res/drawable/ic_launcher.png '160': res/drawable/ic_launcher.png minSdkVersion: 4 +name: urzip packageName: info.guardianproject.urzip sig: e0ecb5fc2d63088e4a07ae410a127722 signer: 7eabd8c15de883d1e82b5df2fd4f7f769e498078e9ad6dc901f0e96db77ceac3 diff --git a/tests/metadata/apk/org.dyndns.fules.ck.yaml b/tests/metadata/apk/org.dyndns.fules.ck.yaml index 76f7cacb..23a0325f 100644 --- a/tests/metadata/apk/org.dyndns.fules.ck.yaml +++ b/tests/metadata/apk/org.dyndns.fules.ck.yaml @@ -14,6 +14,7 @@ icons_src: '160': res/drawable-mdpi-v4/icon_launcher.png '240': res/drawable-hdpi-v4/icon_launcher.png minSdkVersion: 7 +name: Compass Keyboard nativecode: - arm64-v8a - armeabi diff --git a/tests/run-tests b/tests/run-tests index ea878c83..282b8e70 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -24,8 +24,13 @@ copy_apks_into_repo() { echo "$f --> repo/$apk" ln "$f" $1/repo/$apk || \ rsync -axv "$f" $1/repo/$apk # rsync if hard link is not possible + touch $1/.found-apks fi done + if [ ! -e $1/.found-apks ]; then + echo "ERROR: The dir APKDIR must have APKs in it! $APKDIR does not." + exit 1 + fi set -x } diff --git a/tests/update.TestCase b/tests/update.TestCase index 4f9c3f3f..30a93f1f 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -458,98 +458,72 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.config = config fdroidserver.update.config = config os.chdir(os.path.join(localmodule, 'tests')) - try: - config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') - except fdroidserver.exception.FDroidException: - pass # aapt is not required if androguard is present - for use_androguard in (True, False): - if use_androguard: - try: - import androguard - androguard - - def func(): - return True - fdroidserver.common.use_androguard = func - except ImportError: - continue - else: - if 'aapt' in config: - def func(): - return False - fdroidserver.common.use_androguard = func - else: - continue - - print('USE_ANDROGUARD', use_androguard) - - apksigner = fdroidserver.common.find_apksigner() - if apksigner: - if use_androguard: # v2 parsing needs both - config['apksigner'] = apksigner - apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v2-only') - self.assertEqual(apk_info.get('versionCode'), 2) - else: - print('WARNING: skipping v2-only test since apksigner cannot be found') - apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') + apksigner = fdroidserver.common.find_apksigner() + if apksigner: + config['apksigner'] = apksigner + apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), 'v1+2') - self.assertEqual(apk_info.get('versionCode'), 1020) + self.assertEqual(apk_info.get('versionName'), 'v2-only') + self.assertEqual(apk_info.get('versionCode'), 2) + else: + print('WARNING: skipping v2-only test since apksigner cannot be found') + apk_info = fdroidserver.update.scan_apk('repo/v1.v2.sig_1020.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), 'v1+2') + self.assertEqual(apk_info.get('versionCode'), 1020) - apk_info = fdroidserver.update.scan_apk('repo/souch.smsbypass_9.apk') - self.assertIsNone(apk_info.get('maxSdkVersion')) - self.assertEqual(apk_info.get('versionName'), '0.9') + apk_info = fdroidserver.update.scan_apk('repo/souch.smsbypass_9.apk') + self.assertIsNone(apk_info.get('maxSdkVersion')) + self.assertEqual(apk_info.get('versionName'), '0.9') - apk_info = fdroidserver.update.scan_apk('repo/duplicate.permisssions_9999999.apk') - self.assertEqual(apk_info.get('versionName'), '') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_launcher.png', - '-1': 'res/drawable/ic_launcher.png'}) + apk_info = fdroidserver.update.scan_apk('repo/duplicate.permisssions_9999999.apk') + self.assertEqual(apk_info.get('versionName'), '') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_launcher.png', + '-1': 'res/drawable/ic_launcher.png'}) - apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk') - self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png', - '120': 'res/drawable-ldpi-v4/icon_launcher.png', - '160': 'res/drawable-mdpi-v4/icon_launcher.png', - '-1': 'res/drawable-mdpi-v4/icon_launcher.png'}) - self.assertEqual(apk_info['icons'], {}) - self.assertEqual(apk_info['features'], []) - self.assertEqual(apk_info['antiFeatures'], set()) - self.assertEqual(apk_info['versionName'], 'v1.6pre2') - self.assertEqual(apk_info['hash'], - '897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8') - self.assertEqual(apk_info['packageName'], 'org.dyndns.fules.ck') - self.assertEqual(apk_info['versionCode'], 20) - self.assertEqual(apk_info['size'], 132453) - self.assertEqual(apk_info['nativecode'], - ['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']) - self.assertEqual(apk_info['minSdkVersion'], 7) - self.assertEqual(apk_info['sig'], '9bf7a6a67f95688daec75eab4b1436ac') - self.assertEqual(apk_info['hashType'], 'sha256') - self.assertEqual(apk_info['targetSdkVersion'], 8) + apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk') + self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png', + '120': 'res/drawable-ldpi-v4/icon_launcher.png', + '160': 'res/drawable-mdpi-v4/icon_launcher.png', + '-1': 'res/drawable-mdpi-v4/icon_launcher.png'}) + self.assertEqual(apk_info['icons'], {}) + self.assertEqual(apk_info['features'], []) + self.assertEqual(apk_info['antiFeatures'], set()) + self.assertEqual(apk_info['versionName'], 'v1.6pre2') + self.assertEqual(apk_info['hash'], + '897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8') + self.assertEqual(apk_info['packageName'], 'org.dyndns.fules.ck') + self.assertEqual(apk_info['versionCode'], 20) + self.assertEqual(apk_info['size'], 132453) + self.assertEqual(apk_info['nativecode'], + ['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']) + self.assertEqual(apk_info['minSdkVersion'], 7) + self.assertEqual(apk_info['sig'], '9bf7a6a67f95688daec75eab4b1436ac') + self.assertEqual(apk_info['hashType'], 'sha256') + self.assertEqual(apk_info['targetSdkVersion'], 8) - apk_info = fdroidserver.update.scan_apk('org.bitbucket.tickytacky.mirrormirror_4.apk') - self.assertEqual(apk_info.get('versionName'), '1.0.3') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable-mdpi/mirror.png', - '-1': 'res/drawable-mdpi/mirror.png'}) + apk_info = fdroidserver.update.scan_apk('org.bitbucket.tickytacky.mirrormirror_4.apk') + self.assertEqual(apk_info.get('versionName'), '1.0.3') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable-mdpi/mirror.png', + '-1': 'res/drawable-mdpi/mirror.png'}) - apk_info = fdroidserver.update.scan_apk('repo/info.zwanenburg.caffeinetile_4.apk') - self.assertEqual(apk_info.get('versionName'), '1.3') - self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_coffee_on.xml', - '-1': 'res/drawable/ic_coffee_on.xml'}) + apk_info = fdroidserver.update.scan_apk('repo/info.zwanenburg.caffeinetile_4.apk') + self.assertEqual(apk_info.get('versionName'), '1.3') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_coffee_on.xml', + '-1': 'res/drawable/ic_coffee_on.xml'}) - apk_info = fdroidserver.update.scan_apk('repo/com.politedroid_6.apk') - self.assertEqual(apk_info.get('versionName'), '1.5') - self.assertEqual(apk_info['icons_src'], {'120': 'res/drawable-ldpi-v4/icon.png', - '160': 'res/drawable-mdpi-v4/icon.png', - '240': 'res/drawable-hdpi-v4/icon.png', - '320': 'res/drawable-xhdpi-v4/icon.png', - '-1': 'res/drawable-mdpi-v4/icon.png'}) + apk_info = fdroidserver.update.scan_apk('repo/com.politedroid_6.apk') + self.assertEqual(apk_info.get('versionName'), '1.5') + self.assertEqual(apk_info['icons_src'], {'120': 'res/drawable-ldpi-v4/icon.png', + '160': 'res/drawable-mdpi-v4/icon.png', + '240': 'res/drawable-hdpi-v4/icon.png', + '320': 'res/drawable-xhdpi-v4/icon.png', + '-1': 'res/drawable-mdpi-v4/icon.png'}) - apk_info = fdroidserver.update.scan_apk('SpeedoMeterApp.main_1.apk') - self.assertEqual(apk_info.get('versionName'), '1.0') - self.assertEqual(apk_info['icons_src'], {}) + apk_info = fdroidserver.update.scan_apk('SpeedoMeterApp.main_1.apk') + self.assertEqual(apk_info.get('versionName'), '1.0') + self.assertEqual(apk_info['icons_src'], {}) def test_scan_apk_no_min_target(self): config = dict() @@ -627,8 +601,6 @@ class UpdateTest(unittest.TestCase): # Don't care about the date added to the repo and relative apkName del apk['added'] del apk['apkName'] - # avoid AAPT application name bug - del apk['name'] # ensure that icons have been extracted properly if apkName == '../urzip.apk':