diff --git a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java index 521ce3764..8009fc403 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java +++ b/app/src/main/java/org/fdroid/fdroid/RepoXMLHandler.java @@ -128,6 +128,9 @@ public class RepoXMLHandler extends DefaultHandler { case "sdkver": curapk.minSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MIN_VALUE); break; + case "targetSdkVersion": + curapk.targetSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MIN_VALUE); + break; case "maxsdkver": curapk.maxSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MAX_VALUE); if (curapk.maxSdkVersion == 0) { 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 81d84d6ce..48a02ea2f 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Apk.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Apk.java @@ -26,6 +26,7 @@ public class Apk extends ValueObject implements Comparable { public String hash; public String hashType; public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown + public int targetSdkVersion = 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 @@ -93,6 +94,9 @@ public class Apk extends ValueObject implements Comparable { case ApkProvider.DataColumns.MIN_SDK_VERSION: minSdkVersion = cursor.getInt(i); break; + case ApkProvider.DataColumns.TARGET_SDK_VERSION: + targetSdkVersion = cursor.getInt(i); + break; case ApkProvider.DataColumns.MAX_SDK_VERSION: maxSdkVersion = cursor.getInt(i); break; @@ -198,6 +202,7 @@ public class Apk extends ValueObject implements Comparable { values.put(ApkProvider.DataColumns.SIZE, size); values.put(ApkProvider.DataColumns.NAME, apkName); values.put(ApkProvider.DataColumns.MIN_SDK_VERSION, minSdkVersion); + values.put(ApkProvider.DataColumns.TARGET_SDK_VERSION, targetSdkVersion); values.put(ApkProvider.DataColumns.MAX_SDK_VERSION, maxSdkVersion); values.put(ApkProvider.DataColumns.ADDED_DATE, Utils.formatDate(added, "")); values.put(ApkProvider.DataColumns.PERMISSIONS, Utils.CommaSeparatedList.str(permissions)); diff --git a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java index 70b43b739..ef0ffb01f 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java @@ -208,6 +208,7 @@ public class ApkProvider extends FDroidProvider { String SIGNATURE = "sig"; String SOURCE_NAME = "srcname"; String MIN_SDK_VERSION = "minSdkVersion"; + String TARGET_SDK_VERSION = "targetSdkVersion"; String MAX_SDK_VERSION = "maxSdkVersion"; String PERMISSIONS = "permissions"; String FEATURES = "features"; @@ -221,7 +222,7 @@ public class ApkProvider extends FDroidProvider { String[] ALL = { _ID, PACKAGE_NAME, VERSION_NAME, REPO_ID, HASH, VERSION_CODE, NAME, - SIZE, SIGNATURE, SOURCE_NAME, MIN_SDK_VERSION, MAX_SDK_VERSION, + SIZE, SIGNATURE, SOURCE_NAME, MIN_SDK_VERSION, TARGET_SDK_VERSION, MAX_SDK_VERSION, PERMISSIONS, FEATURES, NATIVE_CODE, HASH_TYPE, ADDED_DATE, IS_COMPATIBLE, REPO_VERSION, REPO_ADDRESS, INCOMPATIBLE_REASONS, }; 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 1f38c9a85..9bc6f32fb 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/App.java +++ b/app/src/main/java/org/fdroid/fdroid/data/App.java @@ -329,9 +329,10 @@ public class App extends ValueObject implements Comparable { apk.versionName = packageInfo.versionName; apk.versionCode = packageInfo.versionCode; apk.added = this.added; - int[] minMaxSdkVersions = getMinMaxSdkVersions(context, packageName); - apk.minSdkVersion = minMaxSdkVersions[0]; - apk.maxSdkVersion = minMaxSdkVersions[1]; + int[] minTargetMax = getMinTargetMaxSdkVersions(context, packageName); + apk.minSdkVersion = minTargetMax[0]; + apk.targetSdkVersion = minTargetMax[1]; + apk.maxSdkVersion = minTargetMax[2]; apk.packageName = this.packageName; apk.permissions = Utils.CommaSeparatedList.make(packageInfo.requestedPermissions); apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk"; @@ -509,11 +510,16 @@ public class App extends ValueObject implements Comparable { } /** - * {@link PackageManager} doesn't give us {@code minSdkVersion} and {@code maxSdkVersion}, - * so we have to parse it straight from {@code } in {@code AndroidManifest.xml}. + * {@link PackageManager} doesn't give us {@code minSdkVersion}, {@code targetSdkVersion}, + * and {@code maxSdkVersion}, so we have to parse it straight from {@code } in + * {@code AndroidManifest.xml}. If {@code targetSdkVersion} is not set, then it is + * equal to {@code minSdkVersion} + * + * @see <uses-sdk> element */ - private static int[] getMinMaxSdkVersions(Context context, String packageName) { + private static int[] getMinTargetMaxSdkVersions(Context context, String packageName) { int minSdkVersion = Apk.SDK_VERSION_MIN_VALUE; + int targetSdkVersion = Apk.SDK_VERSION_MIN_VALUE; int maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE; try { AssetManager am = context.createPackageContext(packageName, 0).getAssets(); @@ -524,6 +530,8 @@ public class App extends ValueObject implements Comparable { 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("targetSdkVersion")) { + targetSdkVersion = Integer.parseInt(xml.getAttributeValue(j)); } else if (xml.getAttributeName(j).equals("maxSdkVersion")) { maxSdkVersion = Integer.parseInt(xml.getAttributeValue(j)); } @@ -535,6 +543,9 @@ public class App extends ValueObject implements Comparable { } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { Log.e(TAG, "Could not get min/max sdk version", e); } - return new int[]{minSdkVersion, maxSdkVersion}; + if (targetSdkVersion < minSdkVersion) { + targetSdkVersion = minSdkVersion; + } + return new int[]{minSdkVersion, targetSdkVersion, maxSdkVersion}; } } diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 5890126d5..4d702dcf8 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -51,6 +51,7 @@ class DBHelper extends SQLiteOpenHelper { + "sig string, " + "srcname string, " + "minSdkVersion integer, " + + "targetSdkVersion integer, " + "maxSdkVersion integer, " + "permissions string, " + "features string, " @@ -110,7 +111,7 @@ class DBHelper extends SQLiteOpenHelper { + " );"; private static final String DROP_TABLE_INSTALLED_APP = "DROP TABLE " + TABLE_INSTALLED_APP + ";"; - private static final int DB_VERSION = 56; + private static final int DB_VERSION = 57; private final Context context; @@ -299,6 +300,7 @@ class DBHelper extends SQLiteOpenHelper { useMaxValueInMaxSdkVersion(db, oldVersion); requireTimestampInRepos(db, oldVersion); recreateInstalledAppTable(db, oldVersion); + addTargetSdkVersionToApk(db, oldVersion); } /** @@ -572,6 +574,16 @@ class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_INSTALLED_APP); } + private void addTargetSdkVersionToApk(SQLiteDatabase db, int oldVersion) { + if (oldVersion >= 57) { + return; + } + Utils.debugLog(TAG, "Adding " + ApkProvider.DataColumns.TARGET_SDK_VERSION + + " columns to " + TABLE_APK); + db.execSQL("alter table " + TABLE_APK + " add column " + + ApkProvider.DataColumns.TARGET_SDK_VERSION + " integer"); + } + private static boolean columnExists(SQLiteDatabase db, String table, String column) { return db.rawQuery("select * from " + table + " limit 0,1", null) 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 1e18438f7..a22146ced 100644 --- a/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java +++ b/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java @@ -421,6 +421,9 @@ public final class LocalRepoManager { if (app.installedApk.minSdkVersion > Apk.SDK_VERSION_MIN_VALUE) { tag("sdkver", app.installedApk.minSdkVersion); } + if (app.installedApk.targetSdkVersion > app.installedApk.minSdkVersion) { + tag("targetSdkVersion", app.installedApk.targetSdkVersion); + } if (app.installedApk.maxSdkVersion < Apk.SDK_VERSION_MAX_VALUE) { tag("maxsdkver", app.installedApk.maxSdkVersion); }