diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java index 9b3d01877..166d838f0 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java @@ -27,12 +27,12 @@ public class InstalledAppProvider extends FDroidProvider { public static class Helper { /** - * @return The keys are the app ids (package names), and their corresponding values are - * the version code which is installed. + * @return The keys are the package names, and their corresponding values are + * the {@link PackageInfo#lastUpdateTime last update time} in milliseconds. */ - public static Map all(Context context) { + public static Map all(Context context) { - Map cachedInfo = new HashMap<>(); + Map cachedInfo = new HashMap<>(); final Uri uri = InstalledAppProvider.getContentUri(); final String[] projection = InstalledAppProvider.DataColumns.ALL; @@ -43,7 +43,7 @@ public class InstalledAppProvider extends FDroidProvider { while (!cursor.isAfterLast()) { cachedInfo.put( cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.PACKAGE_NAME)), - cursor.getInt(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_CODE)) + cursor.getLong(cursor.getColumnIndex(DataColumns.LAST_UPDATE_TIME)) ); cursor.moveToNext(); } @@ -223,6 +223,11 @@ public class InstalledAppProvider extends FDroidProvider { return getAppUri(values.getAsString(DataColumns.PACKAGE_NAME)); } + /** + * Update is not supported for {@code InstalledAppProvider}. Instead, use + * {@link #insert(Uri, ContentValues)}, and it will overwrite the relevant + * row, if one exists. This just throws {@link UnsupportedOperationException} + */ @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { throw new UnsupportedOperationException("\"Update' not supported for installed appp provider. Instead, you should insert, and it will overwrite the relevant rows if one exists."); diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java index acd5a8d45..3dc103bac 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java @@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit; * versus what Android says is installed, or processing {@link Intent}s that come * from {@link android.content.BroadcastReceiver}s for {@link Intent#ACTION_PACKAGE_ADDED} * and {@link Intent#ACTION_PACKAGE_REMOVED} - *

+ *

* Since {@link android.content.ContentProvider#insert(Uri, ContentValues)} does not check * for duplicate records, it is entirely the job of this service to ensure that it is not * inserting duplicate versions of the same installed APK. On that note, @@ -94,7 +94,7 @@ public class InstalledAppProviderService extends IntentService { * is in sync with what the {@link PackageManager} tells us is installed. Once * completed, the relevant {@link android.content.ContentProvider}s will be * notified of any changes to installed statuses. - *

+ *

* The installed app cache could get out of sync, e.g. if F-Droid crashed/ or * ran out of battery half way through responding to {@link Intent#ACTION_PACKAGE_ADDED}. * This method returns immediately, and will continue to work in an @@ -103,15 +103,18 @@ public class InstalledAppProviderService extends IntentService { * {@link Process#THREAD_PRIORITY_LOWEST}. */ public static void compareToPackageManager(Context context) { - Map cachedInfo = InstalledAppProvider.Helper.all(context); + Map cachedInfo = InstalledAppProvider.Helper.all(context); List packageInfoList = context.getPackageManager() .getInstalledPackages(PackageManager.GET_SIGNATURES); - // TODO check packageInfo.lastUpdateTime for freshness for (PackageInfo packageInfo : packageInfoList) { - insert(context, packageInfo); if (cachedInfo.containsKey(packageInfo.packageName)) { + if (packageInfo.lastUpdateTime > cachedInfo.get(packageInfo.packageName)) { + insert(context, packageInfo); + } cachedInfo.remove(packageInfo.packageName); + } else { + insert(context, packageInfo); } }