diff --git a/app/src/androidTest/java/mock/MockApplicationInfo.java b/app/src/androidTest/java/mock/MockApplicationInfo.java index abd6c2e22..4d88d3f9b 100644 --- a/app/src/androidTest/java/mock/MockApplicationInfo.java +++ b/app/src/androidTest/java/mock/MockApplicationInfo.java @@ -1,9 +1,11 @@ package mock; +import android.annotation.SuppressLint; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +@SuppressLint("ParcelCreator") public class MockApplicationInfo extends ApplicationInfo { private final PackageInfo info; diff --git a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java index ca2d5ed9c..521ce3764 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java +++ b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java @@ -126,10 +126,14 @@ public class RepoXMLHandler extends DefaultHandler { curapk.apkName = str; break; case "sdkver": - curapk.minSdkVersion = Utils.parseInt(str, 0); + curapk.minSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MIN_VALUE); break; case "maxsdkver": - curapk.maxSdkVersion = Utils.parseInt(str, 0); + curapk.maxSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MAX_VALUE); + if (curapk.maxSdkVersion == 0) { + // before fc0df0dcf4dd0d5f13de82d7cd9254b2b48cb62d, this could be 0 + curapk.maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE; + } break; case "added": curapk.added = Utils.parseDate(str, null); diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index 733280f52..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; @@ -42,8 +40,6 @@ import org.fdroid.fdroid.compat.FileCompat; 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; @@ -224,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 getMinMaxSdkVersion(Context context, String packageName, - String attrName) { - 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 0; - } - - public static int getMinSdkVersion(Context context, String packageName) { - return getMinMaxSdkVersion(context, packageName, "minSdkVersion"); - } - - public static int getMaxSdkVersion(Context context, String packageName) { - return getMinMaxSdkVersion(context, packageName, "maxSdkVersion"); - } - // 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/Apk.java b/app/src/main/java/org/fdroid/fdroid/data/Apk.java index 377bf37bf..98844f15b 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Apk.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Apk.java @@ -14,6 +14,7 @@ public class Apk extends ValueObject implements Comparable { // Using only byte-range keeps it only 8-bits in the SQLite database public static final int SDK_VERSION_MAX_VALUE = Byte.MAX_VALUE; + public static final int SDK_VERSION_MIN_VALUE = 0; public String packageName; public String versionName; @@ -22,7 +23,7 @@ public class Apk extends ValueObject implements Comparable { public long repo; // ID of the repo it comes from public String hash; public String hashType; - public int minSdkVersion; // 0 if unknown + public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown public int maxSdkVersion = SDK_VERSION_MAX_VALUE; // "infinity" if not set public Date added; public Utils.CommaSeparatedList permissions; // null if empty or 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}; + } } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 809825921..144eeef95 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -240,7 +240,7 @@ public class InstallManagerService extends Service { if (AppDetails.isAppVisible(apk.packageName)) { cancelNotification(urlString); } else { - notifyDownloadComplete(urlString, builder, apk); + notifyDownloadComplete(urlString, apk); } unregisterDownloaderReceivers(urlString); } @@ -312,9 +312,14 @@ public class InstallManagerService extends Service { /** * Post a notification about a completed download. {@code packageName} must be a valid - * and currently in the app index database. + * and currently in the app index database. This must create a new {@code Builder} + * instance otherwise the progress/cancel stuff does not go away. + * + * @see Issue 47809: + * Removing the progress bar from a notification should cause the notification's content + * text to return to normal size */ - private void notifyDownloadComplete(String urlString, NotificationCompat.Builder builder, Apk apk) { + private void notifyDownloadComplete(String urlString, Apk apk) { String title; try { PackageManager pm = getPackageManager(); @@ -325,12 +330,16 @@ public class InstallManagerService extends Service { } int downloadUrlId = urlString.hashCode(); - builder.setAutoCancel(true) + notificationManager.cancel(downloadUrlId); + Notification notification = new NotificationCompat.Builder(this) + .setAutoCancel(true) .setOngoing(false) .setContentTitle(title) + .setContentIntent(getAppDetailsIntent(downloadUrlId, apk)) .setSmallIcon(android.R.drawable.stat_sys_download_done) - .setContentText(getString(R.string.tap_to_install)); - notificationManager.notify(downloadUrlId, builder.build()); + .setContentText(getString(R.string.tap_to_install)) + .build(); + notificationManager.notify(downloadUrlId, notification); } /** diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java b/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java index 5826ba062..9b49f0ba1 100644 --- a/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java +++ b/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java @@ -23,6 +23,7 @@ import org.fdroid.fdroid.Hasher; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; +import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.SanitizedFile; import org.xmlpull.v1.XmlPullParserException; @@ -452,9 +453,13 @@ public final class LocalRepoManager { tagHash(app); tag("sig", app.installedApk.sig.toLowerCase(Locale.US)); tag("size", app.installedApk.installedFile.length()); - tag("sdkver", app.installedApk.minSdkVersion); - tag("maxsdkver", app.installedApk.maxSdkVersion); tag("added", app.installedApk.added); + if (app.installedApk.minSdkVersion > Apk.SDK_VERSION_MIN_VALUE) { + tag("sdkver", app.installedApk.minSdkVersion); + } + if (app.installedApk.maxSdkVersion < Apk.SDK_VERSION_MAX_VALUE) { + tag("maxsdkver", app.installedApk.maxSdkVersion); + } tagFeatures(app); tagPermissions(app); tagNativecode(app);