Merge branch 'fix/41' into 'master'

Do not list incompatible app

Closes #41

See merge request fdroid/fdroidclient!1212
This commit is contained in:
Torsten Grote
2023-10-10 15:05:35 +00:00
7 changed files with 73 additions and 10 deletions

View File

@@ -342,13 +342,6 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
configureProxy(preferences);
// If the user changes the preference to do with filtering anti-feature apps,
// it is easier to just notify a change in the app provider,
// so that the newly updated list will correctly filter relevant apps.
preferences.registerAppsRequiringAntiFeaturesChangeListener(() -> {
// TODO check if anything else needs updating/reloading
});
preferences.registerUnstableUpdatesChangeListener(() ->
AppUpdateStatusManager.getInstance(FDroidApp.this).checkForUpdates());

View File

@@ -182,6 +182,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
private final List<ChangeListener> localRepoNameListeners = new ArrayList<>();
private final List<ChangeListener> localRepoHttpsListeners = new ArrayList<>();
private final List<ChangeListener> unstableUpdatesListeners = new ArrayList<>();
private final List<ChangeListener> showIncompatibleListeners = new ArrayList<>();
private boolean isInitialized(String key) {
return initialized.containsKey(key) && initialized.get(key);
@@ -616,6 +617,14 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
unstableUpdatesListeners.add(listener);
}
public void registerShowIncompatibleListener(ChangeListener listener) {
showIncompatibleListeners.add(listener);
}
public void unregisterShowIncompatibleListener(ChangeListener listener) {
showIncompatibleListeners.remove(listener);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Utils.debugLog(TAG, "Invalidating preference '" + key + "'.");
@@ -642,6 +651,11 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
listener.onPreferenceChange();
}
break;
case PREF_SHOW_INCOMPAT_VERSIONS:
for (ChangeListener listener : showIncompatibleListeners) {
listener.onPreferenceChange();
}
break;
}
}

View File

@@ -57,11 +57,13 @@ class LatestViewBinder implements Observer<List<AppOverviewItem>>, ChangeListene
@Override
public void onCreate(@NonNull LifecycleOwner owner) {
Preferences.get().registerAppsRequiringAntiFeaturesChangeListener(LatestViewBinder.this);
Preferences.get().registerShowIncompatibleListener(LatestViewBinder.this);
}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
Preferences.get().unregisterAppsRequiringAntiFeaturesChangeListener(LatestViewBinder.this);
Preferences.get().unregisterShowIncompatibleListener(LatestViewBinder.this);
}
});
db = DBHelper.getDb(activity);
@@ -135,11 +137,14 @@ class LatestViewBinder implements Observer<List<AppOverviewItem>>, ChangeListene
Set<String> shownAntiFeatures = Preferences.get().showAppsWithAntiFeatures();
String otherAntiFeatures = activity.getResources().getString(R.string.antiothers_key);
boolean showOtherAntiFeatures = shownAntiFeatures.contains(otherAntiFeatures);
boolean hideIncompatibleVersions = !Preferences.get().showIncompatibleVersions();
Iterator<AppOverviewItem> iterator = items.iterator();
while (iterator.hasNext()) {
AppOverviewItem item = iterator.next();
if (isFilteredByAntiFeature(item, antiFeatures, shownAntiFeatures, showOtherAntiFeatures)) {
iterator.remove();
} else if (hideIncompatibleVersions && !item.isCompatible()) {
iterator.remove();
}
}
}

View File

@@ -10,8 +10,10 @@ import org.fdroid.test.TestVersionUtils.getRandomPackageVersionV2
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
@RunWith(AndroidJUnit4::class)
internal class AppOverviewItemsTest : AppTest() {
@@ -89,6 +91,50 @@ internal class AppOverviewItemsTest : AppTest() {
assertEquals(3, appDao.getAppOverviewItems(42).getOrFail().size)
}
@Test
fun testIncompatibleFlag() {
// insert two apps
val repoId = repoDao.insertOrReplace(getRandomRepo())
appDao.insert(repoId, packageName1, app1, locales)
appDao.insert(repoId, packageName2, app2, locales)
// both apps are not compatible
appDao.getAppOverviewItems().getOrFail().also {
assertEquals(2, it.size)
}.forEach {
assertFalse(it.isCompatible)
}
// both apps, in the same category, are not compatible
appDao.getAppOverviewItems("A").getOrFail().also {
assertEquals(2, it.size)
}.forEach {
assertFalse(it.isCompatible)
}
assertFalse(appDao.getAppOverviewItem(repoId, packageName1)!!.isCompatible)
assertFalse(appDao.getAppOverviewItem(repoId, packageName2)!!.isCompatible)
// each app gets a version
versionDao.insert(repoId, packageName1, "1", getRandomPackageVersionV2(), true)
versionDao.insert(repoId, packageName2, "1", getRandomPackageVersionV2(), false)
// updating compatibility for apps
appDao.updateCompatibility(repoId)
// now only one is not compatible
appDao.getAppOverviewItems().getOrFail().also {
assertEquals(2, it.size)
assertFalse(it[0].isCompatible)
assertTrue(it[1].isCompatible)
}
appDao.getAppOverviewItems("A").getOrFail().also {
assertEquals(2, it.size)
assertFalse(it[0].isCompatible)
assertTrue(it[1].isCompatible)
}
assertTrue(appDao.getAppOverviewItem(repoId, packageName1)!!.isCompatible)
assertFalse(appDao.getAppOverviewItem(repoId, packageName2)!!.isCompatible)
}
@Test
fun testGetByRepoWeight() {
// insert one app with one version

View File

@@ -250,6 +250,10 @@ public data class AppOverviewItem internal constructor(
entityColumn = "packageName",
)
internal val localizedIcon: List<LocalizedIcon>? = null,
/**
* If true, this this app has at least one version that is compatible with this device.
*/
public val isCompatible: Boolean,
) : MinimalApp {
public override fun getIcon(localeList: LocaleListCompat): FileV2? {
return localizedIcon?.filter { icon ->

View File

@@ -326,7 +326,7 @@ internal interface AppDaoInt : AppDao {
@Transaction
@Query("""SELECT repoId, packageName, app.added, app.lastUpdated, localizedName,
localizedSummary, version.antiFeatures
localizedSummary, version.antiFeatures, app.isCompatible
FROM ${AppMetadata.TABLE} AS app
JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId)
LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName)
@@ -340,7 +340,7 @@ internal interface AppDaoInt : AppDao {
@Transaction
@Query("""SELECT repoId, packageName, app.added, app.lastUpdated, localizedName,
localizedSummary, version.antiFeatures
localizedSummary, version.antiFeatures, app.isCompatible
FROM ${AppMetadata.TABLE} AS app
JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId)
LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName)
@@ -358,7 +358,7 @@ internal interface AppDaoInt : AppDao {
@Transaction
@SuppressWarnings(CURSOR_MISMATCH) // no anti-features needed here
@Query("""SELECT repoId, packageName, added, app.lastUpdated, localizedName,
localizedSummary
localizedSummary, app.isCompatible
FROM ${AppMetadata.TABLE} AS app WHERE repoId = :repoId AND packageName = :packageName""")
fun getAppOverviewItem(repoId: Long, packageName: String): AppOverviewItem?

View File

@@ -74,6 +74,7 @@ internal open class RepoV2StreamReceiver(
ipfsCidV1 = file.ipfsCidV1,
)
},
isCompatible = true, // not concerned with compatibility at this point
)
}