diff --git a/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java b/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java index 7c96e66e2..7da03fcd0 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java @@ -11,23 +11,10 @@ import mock.MockInstallablePackageManager; @SuppressWarnings("PMD") // TODO port this to JUnit 4 semantics public class InstalledAppProviderTest extends FDroidProviderTest { - private MockInstallablePackageManager packageManager; - public InstalledAppProviderTest() { super(InstalledAppProvider.class, InstalledAppProvider.getAuthority()); } - @Override - public void setUp() throws Exception { - super.setUp(); - packageManager = new MockInstallablePackageManager(); - getSwappableContext().setPackageManager(packageManager); - } - - protected MockInstallablePackageManager getPackageManager() { - return packageManager; - } - public void testUris() { assertInvalidUri(InstalledAppProvider.getAuthority()); assertInvalidUri(RepoProvider.getContentUri()); @@ -130,45 +117,6 @@ public class InstalledAppProviderTest extends FDroidProviderTest notifyEvents; public InstalledAppProviderService() { super("InstalledAppProviderService"); } + @Override + public void onCreate() { + super.onCreate(); + notifyEvents = PublishSubject.create(); + notifyEvents.debounce(1, TimeUnit.SECONDS) + .subscribeOn(Schedulers.newThread()) + .subscribe(new Action1() { + @Override + public void call(Void voidArg) { + Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views)."); + getContentResolver().notifyChange(AppProvider.getContentUri(), null); + getContentResolver().notifyChange(ApkProvider.getContentUri(), null); + } + }); + } + /** * Inserts an app into {@link InstalledAppProvider} based on a {@code package:} {@link Uri}. * This has no checks for whether it is inserting an exact duplicate, whatever is provided @@ -134,7 +160,7 @@ public class InstalledAppProviderService extends IntentService { } else if (ACTION_DELETE.equals(action)) { deleteAppFromDb(this, packageName); } - notifyChange(); + notifyEvents.onNext(null); } } @@ -156,8 +182,7 @@ public class InstalledAppProviderService extends IntentService { contentValues.put(InstalledAppProvider.DataColumns.VERSION_NAME, packageInfo.versionName); contentValues.put(InstalledAppProvider.DataColumns.APPLICATION_LABEL, InstalledAppProvider.getApplicationLabel(context, packageInfo.packageName)); - contentValues.put(InstalledAppProvider.DataColumns.SIGNATURE, - InstalledAppProvider.getPackageSig(packageInfo)); + contentValues.put(InstalledAppProvider.DataColumns.SIGNATURE, getPackageSig(packageInfo)); contentValues.put(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME, packageInfo.lastUpdateTime); String hashType = "sha256"; @@ -173,31 +198,19 @@ public class InstalledAppProviderService extends IntentService { context.getContentResolver().delete(uri, null, null); } - /** - * This notifies the users of this {@link android.content.ContentProvider} - * that the contents has changed. Since {@link Intent}s can come in slow - * or fast, and this can trigger a lot of UI updates, the actual - * notifications are rate limited to one per second. - */ - private void notifyChange() { - notifyChangeNeedsSending = true; - Runnable task = new Runnable() { - @Override - public void run() { - if (notifyChangeNeedsSending) { - Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views)."); - getContentResolver().notifyChange(AppProvider.getContentUri(), null); - getContentResolver().notifyChange(ApkProvider.getContentUri(), null); - notifyChangeNeedsSending = false; - } else { - worker.shutdown(); - worker = null; - } - } - }; - if (worker == null || worker.isShutdown()) { - worker = Executors.newSingleThreadScheduledExecutor(); - worker.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); + private static String getPackageSig(PackageInfo info) { + if (info == null || info.signatures == null || info.signatures.length < 1) { + return ""; } + Signature sig = info.signatures[0]; + String sigHash = ""; + try { + Hasher hash = new Hasher("MD5", sig.toCharsString().getBytes()); + sigHash = hash.getHash(); + } catch (NoSuchAlgorithmException e) { + // ignore + } + return sigHash; } + } \ No newline at end of file diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/CacheSwapAppsService.java b/app/src/main/java/org/fdroid/fdroid/localrepo/CacheSwapAppsService.java index 63a1fa1c0..31d3c880c 100644 --- a/app/src/main/java/org/fdroid/fdroid/localrepo/CacheSwapAppsService.java +++ b/app/src/main/java/org/fdroid/fdroid/localrepo/CacheSwapAppsService.java @@ -37,7 +37,9 @@ public class CacheSwapAppsService extends IntentService { * Parse the locally installed APK for {@code packageName} and save its XML * to the APK XML cache. */ - public static void parseApp(Context context, Intent intent) { + private static void parseApp(Context context, String packageName) { + Intent intent = new Intent(); + intent.setData(Utils.getPackageUri(packageName)); intent.setClass(context, CacheSwapAppsService.class); intent.setAction(ACTION_PARSE_APP); context.startService(intent); @@ -57,9 +59,7 @@ public class CacheSwapAppsService extends IntentService { } if (!indexJarFile.exists() || FileUtils.isFileNewer(new File(applicationInfo.sourceDir), indexJarFile)) { - Intent intent = new Intent(); - intent.setData(Utils.getPackageUri(applicationInfo.packageName)); - parseApp(context, intent); + parseApp(context, applicationInfo.packageName); } } } 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 3cf9b79b3..1e18438f7 100644 --- a/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java +++ b/app/src/main/java/org/fdroid/fdroid/localrepo/LocalRepoManager.java @@ -319,16 +319,6 @@ public final class LocalRepoManager { * Helper class to aid in constructing index.xml file. */ public static final class IndexXmlBuilder { - - private static IndexXmlBuilder indexXmlBuilder; - - public static IndexXmlBuilder get() throws XmlPullParserException { - if (indexXmlBuilder == null) { - indexXmlBuilder = new IndexXmlBuilder(); - } - return indexXmlBuilder; - } - @NonNull private final XmlSerializer serializer; @@ -487,7 +477,7 @@ public final class LocalRepoManager { JarOutputStream jo = new JarOutputStream(bo); JarEntry je = new JarEntry("index.xml"); jo.putNextEntry(je); - IndexXmlBuilder.get().build(context, apps, jo); + new IndexXmlBuilder().build(context, apps, jo); jo.close(); bo.close();