From 887c55247ad9d00869a012cc6935953fefd59aee Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 26 Jan 2018 11:46:04 +0100 Subject: [PATCH] force full index update when system locale changes The database currently only stores the active language. So if the user changes the system language of the phone, then the language of all the app descriptions will be out of sync until the next update. This forces an update when the locale is changed. This functionality is also needed for events like OS upgrades. closes #225 --- .../java/org/fdroid/fdroid/FDroidApp.java | 1 + .../java/org/fdroid/fdroid/UpdateService.java | 39 +++++++++++++------ .../java/org/fdroid/fdroid/data/DBHelper.java | 13 ++++++- .../fdroid/fdroid/localrepo/SwapService.java | 2 +- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java index af4fbc32f..03518b11d 100644 --- a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java +++ b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java @@ -267,6 +267,7 @@ public class FDroidApp extends Application { public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Languages.setLanguage(this); + UpdateService.forceUpdateRepo(this); } @Override diff --git a/app/src/main/java/org/fdroid/fdroid/UpdateService.java b/app/src/main/java/org/fdroid/fdroid/UpdateService.java index e6a02303f..1b9a5a62b 100644 --- a/app/src/main/java/org/fdroid/fdroid/UpdateService.java +++ b/app/src/main/java/org/fdroid/fdroid/UpdateService.java @@ -40,11 +40,11 @@ import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; - import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.AppProvider; +import org.fdroid.fdroid.data.DBHelper; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.Schema; @@ -66,6 +66,7 @@ public class UpdateService extends IntentService { public static final String EXTRA_STATUS_CODE = "status"; public static final String EXTRA_ADDRESS = "address"; public static final String EXTRA_MANUAL_UPDATE = "manualUpdate"; + public static final String EXTRA_FORCED_UPDATE = "forcedUpdate"; public static final String EXTRA_PROGRESS = "progress"; public static final int STATUS_COMPLETE_WITH_CHANGES = 0; @@ -96,10 +97,10 @@ public class UpdateService extends IntentService { } public static void updateNow(Context context) { - updateRepoNow(null, context); + updateRepoNow(context, null); } - public static void updateRepoNow(String address, Context context) { + public static void updateRepoNow(Context context, String address) { Intent intent = new Intent(context, UpdateService.class); intent.putExtra(EXTRA_MANUAL_UPDATE, true); if (!TextUtils.isEmpty(address)) { @@ -108,6 +109,17 @@ public class UpdateService extends IntentService { context.startService(intent); } + /** + * For when an automatic process needs to force an index update, like + * when the system language changes, or the underlying OS was upgraded. + * This wipes the existing database before running the update! + */ + public static void forceUpdateRepo(Context context) { + Intent intent = new Intent(context, UpdateService.class); + intent.putExtra(EXTRA_FORCED_UPDATE, true); + context.startService(intent); + } + /** * Schedule or cancel this service to update the app index, according to the * current preferences. Should be called a) at boot, b) if the preference @@ -225,7 +237,7 @@ public class UpdateService extends IntentService { switch (resultCode) { case STATUS_INFO: notificationBuilder.setContentText(message) - .setCategory(NotificationCompat.CATEGORY_SERVICE); + .setCategory(NotificationCompat.CATEGORY_SERVICE); if (progress != -1) { notificationBuilder.setProgress(100, progress, false); } else { @@ -236,8 +248,8 @@ public class UpdateService extends IntentService { case STATUS_ERROR_GLOBAL: text = context.getString(R.string.global_error_updating_repos, message); notificationBuilder.setContentText(text) - .setCategory(NotificationCompat.CATEGORY_ERROR) - .setSmallIcon(android.R.drawable.ic_dialog_alert); + .setCategory(NotificationCompat.CATEGORY_ERROR) + .setSmallIcon(android.R.drawable.ic_dialog_alert); notificationManager.notify(NOTIFY_ID_UPDATING, notificationBuilder.build()); Toast.makeText(context, text, Toast.LENGTH_LONG).show(); break; @@ -254,8 +266,8 @@ public class UpdateService extends IntentService { } text = msgBuilder.toString(); notificationBuilder.setContentText(text) - .setCategory(NotificationCompat.CATEGORY_ERROR) - .setSmallIcon(android.R.drawable.ic_dialog_info); + .setCategory(NotificationCompat.CATEGORY_ERROR) + .setSmallIcon(android.R.drawable.ic_dialog_info); notificationManager.notify(NOTIFY_ID_UPDATING, notificationBuilder.build()); Toast.makeText(context, text, Toast.LENGTH_LONG).show(); break; @@ -264,7 +276,7 @@ public class UpdateService extends IntentService { case STATUS_COMPLETE_AND_SAME: text = context.getString(R.string.repos_unchanged); notificationBuilder.setContentText(text) - .setCategory(NotificationCompat.CATEGORY_SERVICE); + .setCategory(NotificationCompat.CATEGORY_SERVICE); notificationManager.notify(NOTIFY_ID_UPDATING, notificationBuilder.build()); break; } @@ -349,10 +361,12 @@ public class UpdateService extends IntentService { final long startTime = System.currentTimeMillis(); boolean manualUpdate = false; + boolean forcedUpdate = false; String address = null; if (intent != null) { address = intent.getStringExtra(EXTRA_ADDRESS); manualUpdate = intent.getBooleanExtra(EXTRA_MANUAL_UPDATE, false); + forcedUpdate = intent.getBooleanExtra(EXTRA_FORCED_UPDATE, false); } try { @@ -366,8 +380,8 @@ public class UpdateService extends IntentService { return; } - if (manualUpdate) { - Utils.debugLog(TAG, "manually requested update"); + if (manualUpdate || forcedUpdate) { + Utils.debugLog(TAG, "manually requested or forced update"); } else if (!verifyIsTimeForScheduledRun() || (netState == FLAG_NET_METERED && Preferences.get().isUpdateOnlyOnUnmeteredNetworks())) { Utils.debugLog(TAG, "don't run update"); @@ -404,6 +418,9 @@ public class UpdateService extends IntentService { sendStatus(this, STATUS_INFO, getString(R.string.status_connecting_to_repo, repo.address)); + if (forcedUpdate) { + DBHelper.resetTransient(this); + } try { RepoUpdater updater = new IndexV1Updater(this, repo); 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 966e00846..d4c671167 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -1091,8 +1091,17 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL("update " + RepoTable.NAME + " set " + RepoTable.Cols.LAST_ETAG + " = NULL"); } - private void resetTransient(SQLiteDatabase db) { - Utils.debugLog(TAG, "Removing app + apk tables so they can be recreated. Next time F-Droid updates it should trigger an index update."); + /** + * Resets all database tables that are generated from the index files downloaded + * from the active repositories. This will trigger the index file(s) to be + * downloaded processed on the next update. + */ + public static void resetTransient(Context context) { + resetTransient(getInstance(context).getWritableDatabase()); + } + + private static void resetTransient(SQLiteDatabase db) { + Utils.debugLog(TAG, "Removing all index tables, they will be recreated next time F-Droid updates."); Preferences.get().setTriedEmptyUpdate(false); diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java b/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java index 5fb70b1bf..b3099cfb5 100644 --- a/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java +++ b/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java @@ -205,7 +205,7 @@ public class SwapService extends Service { askServerToSwapWithUs(peerRepo); } - UpdateService.updateRepoNow(peer.getRepoAddress(), this); + UpdateService.updateRepoNow(this, peer.getRepoAddress()); } private void askServerToSwapWithUs(final Repo repo) {