From f08f8cb53d8918c39c5ce04331c67815a6ed79c1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 23 May 2016 14:26:52 +0200 Subject: [PATCH] only parse once when looking for min/max SDK version When building APK instances from installed apps, the minSdkVersion and maxSdkVersion needs to be parsed directly from the APK's Android Manifest, since PackageManager does not provide a method to get it how we need it. Previously, the whole AndroidManifest.xml file was parsed entirely twice, once for minSdkVersion then for maxSdkVersion. --- .../main/java/org/fdroid/fdroid/Utils.java | 37 ------------------ .../main/java/org/fdroid/fdroid/data/App.java | 39 ++++++++++++++++++- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index a190af20b..c93a6e466 100644 --- a/app/src/main/java/org/fdroid/fdroid/Utils.java +++ b/app/src/main/java/org/fdroid/fdroid/Utils.java @@ -20,8 +20,6 @@ package org.fdroid.fdroid; import android.content.Context; import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.XmlResourceParser; import android.graphics.Bitmap; import android.net.Uri; import android.support.annotation.NonNull; @@ -39,12 +37,9 @@ import com.nostra13.universalimageloader.utils.StorageUtils; import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.compat.FileCompat; -import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.SanitizedFile; import org.xml.sax.XMLReader; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedInputStream; import java.io.Closeable; @@ -225,38 +220,6 @@ public final class Utils { return ANDROID_VERSION_NAMES[sdkLevel]; } - /* PackageManager doesn't give us the min and max sdk versions, so we have - * to parse it */ - private static int getSdkVersion(Context context, String packageName, - String attrName, final int defaultValue) { - try { - AssetManager am = context.createPackageContext(packageName, 0).getAssets(); - XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) { - for (int j = 0; j < xml.getAttributeCount(); j++) { - if (xml.getAttributeName(j).equals(attrName)) { - return Integer.parseInt(xml.getAttributeValue(j)); - } - } - } - eventType = xml.nextToken(); - } - } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { - Log.e(TAG, "Could not get min/max sdk version", e); - } - return defaultValue; - } - - public static int getMinSdkVersion(Context context, String packageName) { - return getSdkVersion(context, packageName, "minSdkVersion", Apk.SDK_VERSION_MIN_VALUE); - } - - public static int getMaxSdkVersion(Context context, String packageName) { - return getSdkVersion(context, packageName, "maxSdkVersion", Apk.SDK_VERSION_MAX_VALUE); - } - // return a fingerprint formatted for display public static String formatFingerprint(Context context, String fingerprint) { if (TextUtils.isEmpty(fingerprint) diff --git a/app/src/main/java/org/fdroid/fdroid/data/App.java b/app/src/main/java/org/fdroid/fdroid/data/App.java index 94e1af011..5e68d540b 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/App.java +++ b/app/src/main/java/org/fdroid/fdroid/data/App.java @@ -7,6 +7,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.FeatureInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.res.AssetManager; +import android.content.res.XmlResourceParser; import android.database.Cursor; import android.os.Parcelable; import android.text.TextUtils; @@ -15,6 +17,8 @@ import android.util.Log; import org.fdroid.fdroid.AppFilter; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Utils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; @@ -293,8 +297,9 @@ public class App extends ValueObject implements Comparable { apk.versionName = packageInfo.versionName; apk.versionCode = packageInfo.versionCode; apk.added = this.added; - apk.minSdkVersion = Utils.getMinSdkVersion(context, packageName); - apk.maxSdkVersion = Utils.getMaxSdkVersion(context, packageName); + int[] minMaxSdkVersions = getMinMaxSdkVersions(context, packageName); + apk.minSdkVersion = minMaxSdkVersions[0]; + apk.maxSdkVersion = minMaxSdkVersions[1]; apk.packageName = this.packageName; apk.permissions = Utils.CommaSeparatedList.make(packageInfo.requestedPermissions); apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk"; @@ -476,4 +481,34 @@ public class App extends ValueObject implements Comparable { public String getSuggestedVersionName() { return suggestedVersionName; } + + /** + * {@link PackageManager} doesn't give us {@code minSdkVersion} and {@code maxSdkVersion}, + * so we have to parse it straight from {@code } in {@code AndroidManifest.xml}. + */ + private static int[] getMinMaxSdkVersions(Context context, String packageName) { + int minSdkVersion = Apk.SDK_VERSION_MIN_VALUE; + int maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE; + try { + AssetManager am = context.createPackageContext(packageName, 0).getAssets(); + XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); + int eventType = xml.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) { + for (int j = 0; j < xml.getAttributeCount(); j++) { + if (xml.getAttributeName(j).equals("minSdkVersion")) { + minSdkVersion = Integer.parseInt(xml.getAttributeValue(j)); + } else if (xml.getAttributeName(j).equals("maxSdkVersion")) { + maxSdkVersion = Integer.parseInt(xml.getAttributeValue(j)); + } + } + break; + } + eventType = xml.nextToken(); + } + } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { + Log.e(TAG, "Could not get min/max sdk version", e); + } + return new int[]{minSdkVersion, maxSdkVersion}; + } }