Merge branch 'targetSdkRequirement' into 'master'

Mark apps with target SDK lower than 23 as incompatiable

See merge request fdroid/fdroidclient!1294
This commit is contained in:
Torsten Grote
2023-10-14 13:22:44 +00:00
7 changed files with 54 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ import android.os.Build;
import androidx.annotation.Nullable;
import org.fdroid.CompatibilityCheckerUtils;
import org.fdroid.fdroid.data.Apk;
import java.util.ArrayList;
@@ -76,6 +77,13 @@ public class CompatibilityChecker {
Utils.getAndroidVersionName(apk.maxSdkVersion)));
}
int minInstallableTargetSdk = CompatibilityCheckerUtils.INSTANCE.minInstallableTargetSdk();
if (apk.targetSdkVersion < minInstallableTargetSdk) {
incompatibleReasons.add(context.getString(
R.string.targetsdk_or_later,
Utils.getAndroidVersionName(minInstallableTargetSdk)));
}
if (apk.features != null) {
for (final String feat : apk.features) {
if (forceTouchApps && "android.hardware.touchscreen".equals(feat)) {

View File

@@ -467,6 +467,7 @@ This often occurs with apps installed via Google Play or other sources, if they
this network: %s
</string>
<string name="requires_features">Requires: %1$s</string>
<string name="targetsdk_or_later">targets %s</string>
<string name="pref_language">Language</string>
<string name="pref_language_default">System Default</string>

View File

@@ -134,6 +134,7 @@ public data class AppManifest(
) : PackageManifest {
public override val minSdkVersion: Int? get() = usesSdk?.minSdkVersion
public override val featureNames: List<String>? get() = features
public override val targetSdkVersion: Int? get() = usesSdk?.targetSdkVersion
}
internal fun ManifestV2.toManifest() = AppManifest(

View File

@@ -30,6 +30,8 @@ public class CompatibilityCheckerImpl @JvmOverloads constructor(
public override fun isCompatible(manifest: PackageManifest): Boolean {
if (sdkInt < manifest.minSdkVersion ?: 0) return false
if (sdkInt > manifest.maxSdkVersion ?: Int.MAX_VALUE) return false
if ((manifest.targetSdkVersion ?: 1) <
CompatibilityCheckerUtils.minInstallableTargetSdk(sdkInt)) return false
if (!isNativeCodeCompatible(manifest)) return false
manifest.featureNames?.iterator()?.forEach { feature ->
if (forceTouchApps && feature == "android.hardware.touchscreen") return@forEach
@@ -47,3 +49,19 @@ public class CompatibilityCheckerImpl @JvmOverloads constructor(
return false
}
}
/**
* Contains helper methods for checking compatibility of an APK
*/
public object CompatibilityCheckerUtils {
// Mirrored from AOSP due to lack of public APIs
// frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
// TODO: Keep this in sync with AOSP to avoid INSTALL_FAILED_DEPRECATED_SDK_VERSION errors
@JvmOverloads
public fun minInstallableTargetSdk(sdkInt: Int = SDK_INT): Int {
return when (sdkInt) {
34 -> 23 // Android 6.0, M
else -> 1 // Android 1.0, BASE
}
}
}

View File

@@ -103,11 +103,34 @@ internal class CompatibilityCheckerTest {
assertFalse(checker.isCompatible(manifest4))
}
@Test
fun targetSdkIsRespected() {
// greater or equal than minInstallableTargetSdk are compatible
val manifest1 = Manifest(targetSdkVersion = Int.MAX_VALUE)
assertTrue(checker.isCompatible(manifest1))
val manifest2 = Manifest(targetSdkVersion = 23)
val checker2 = CompatibilityCheckerImpl(
packageManager = packageManager,
sdkInt = 34,
supportedAbis = emptyArray()
)
assertTrue(checker2.isCompatible(manifest2))
// a targetSdk smaller than minInstallableTargetSdk is not compatible
val manifest3 = Manifest(targetSdkVersion = 22)
val checker3 = CompatibilityCheckerImpl(
packageManager = packageManager,
sdkInt = 34,
supportedAbis = emptyArray()
)
assertFalse(checker3.isCompatible(manifest3))
}
private data class Manifest(
override val minSdkVersion: Int? = null,
override val maxSdkVersion: Int? = null,
override val featureNames: List<String>? = null,
override val nativecode: List<String>? = null,
override val targetSdkVersion: Int? = null,
) : PackageManifest
}

View File

@@ -189,6 +189,7 @@ internal class UpdateCheckerTest {
override val maxSdkVersion: Int? = null
override val featureNames: List<String>? = null
override val nativecode: List<String>? = null
override val targetSdkVersion: Int? = null
},
override val hasKnownVulnerability: Boolean = false,
) : PackageVersion

View File

@@ -137,6 +137,7 @@ public interface PackageManifest {
public val maxSdkVersion: Int?
public val featureNames: List<String>?
public val nativecode: List<String>?
public val targetSdkVersion: Int?
}
@Serializable
@@ -153,6 +154,7 @@ public data class ManifestV2(
) : PackageManifest {
override val minSdkVersion: Int? = usesSdk?.minSdkVersion
override val featureNames: List<String> = features.map { it.name }
override val targetSdkVersion: Int? = usesSdk?.targetSdkVersion
}
@Serializable