From b854331daad3ba7015d896321e36b16bbc68b1bc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 13 Jun 2018 18:20:41 +0200 Subject: [PATCH] Show notification during key sync --- .../keychain/Constants.java | 7 +- .../keychain/keysync/KeyserverSyncWorker.java | 89 +++++++++++++++++-- .../service/PassphraseCacheService.java | 3 +- .../ui/OrbotRequiredDialogActivity.java | 4 +- OpenKeychain/src/main/res/values/strings.xml | 4 + 5 files changed, 97 insertions(+), 10 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 2da51d506..fce89989b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -108,9 +108,14 @@ public final class Constants { public static final File APP_DIR = new File(Environment.getExternalStorageDirectory(), "OpenKeychain"); } - public static final class Notification { + public static final class NotificationIds { public static final int PASSPHRASE_CACHE = 1; public static final int KEYSERVER_SYNC_FAIL_ORBOT = 2; + public static final int KEYSERVER_SYNC = 3; + } + + public static final class NotificationChannels { + public static final String KEYSERVER_SYNC = "keyserverSync"; } public static final class Pref { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java index 240389d83..94b996644 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java @@ -7,16 +7,25 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.content.Context; +import android.os.Build; import android.support.annotation.NonNull; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationCompat.Builder; import androidx.work.Worker; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Constants.NotificationChannels; +import org.sufficientlysecure.keychain.Constants.NotificationIds; +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.network.orbot.OrbotHelper; import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.KeyWritableRepository; import org.sufficientlysecure.keychain.provider.LastUpdateInteractor; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; @@ -24,6 +33,7 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.ResourceUtils; import timber.log.Timber; @@ -65,10 +75,19 @@ public class KeyserverSyncWorker extends Worker { // no explicit proxy, retrieve from preferences. Check if we should do a staggered sync CryptoInputParcel cryptoInputParcel = CryptoInputParcel.createCryptoInputParcel(); - if (preferences.getParcelableProxy().isTorEnabled()) { - return staggeredUpdate(context, staleKeyParcelableKeyRings, cryptoInputParcel); - } else { - return directUpdate(context, staleKeyParcelableKeyRings, cryptoInputParcel); + try { + Progressable notificationProgressable = notificationShowForProgress(); + + ImportKeyResult importKeyResult; + if (preferences.getParcelableProxy().isTorEnabled()) { + importKeyResult = staggeredUpdate(context, staleKeyParcelableKeyRings, cryptoInputParcel); + } else { + importKeyResult = + directUpdate(context, staleKeyParcelableKeyRings, cryptoInputParcel, notificationProgressable); + } + return importKeyResult; + } finally { + notificationRemove(); } } @@ -82,9 +101,9 @@ public class KeyserverSyncWorker extends Worker { } private ImportKeyResult directUpdate(Context context, List keyList, - CryptoInputParcel cryptoInputParcel) { + CryptoInputParcel cryptoInputParcel, Progressable notificationProgressable) { Timber.d("Starting normal update"); - ImportOperation importOp = new ImportOperation(context, keyWritableRepository, null); + ImportOperation importOp = new ImportOperation(context, keyWritableRepository, notificationProgressable); return importOp.execute( ImportKeyringParcel.createImportKeyringParcel(keyList, preferences.getPreferredKeyserver()), cryptoInputParcel @@ -190,6 +209,64 @@ public class KeyserverSyncWorker extends Worker { return accumulator.getConsolidatedResult(); } + private Progressable notificationShowForProgress() { + final Context context = getApplicationContext(); + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) { + return null; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + CharSequence name = context.getString(R.string.notify_channel_keysync); + NotificationChannel channel = new NotificationChannel( + NotificationChannels.KEYSERVER_SYNC, name, NotificationManager.IMPORTANCE_LOW); + notificationManager.createNotificationChannel(channel); + } + + NotificationCompat.Builder builder = new Builder(context, NotificationChannels.KEYSERVER_SYNC) + .setSmallIcon(R.drawable.ic_stat_notify_24dp) + .setLargeIcon(ResourceUtils.getDrawableAsNotificationBitmap(context, R.mipmap.ic_launcher)) + .setContentTitle(context.getString(R.string.notify_title_keysync)) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setProgress(0, 0, true); + + return new Progressable() { + @Override + public void setProgress(String message, int current, int total) { + builder.setProgress(total, current, false); + builder.setContentText(context.getString(R.string.notify_content_keysync, current, total)); + notificationManager.notify(NotificationIds.KEYSERVER_SYNC, builder.build()); + } + + @Override + public void setProgress(int resourceId, int current, int total) { + builder.setProgress(total, current, false); + builder.setContentText(context.getString(R.string.notify_content_keysync, current, total)); + notificationManager.notify(NotificationIds.KEYSERVER_SYNC, builder.build()); + } + + @Override + public void setProgress(int current, int total) { + builder.setProgress(total, current, false); + builder.setContentText(context.getString(R.string.notify_content_keysync, current, total)); + notificationManager.notify(NotificationIds.KEYSERVER_SYNC, builder.build()); + } + + @Override + public void setPreventCancel() { + } + }; + } + + private void notificationRemove() { + NotificationManager notificationManager = + (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.cancel(NotificationIds.KEYSERVER_SYNC); + } + } + @Override public void onStopped() { super.onStopped(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 8945a3652..fe9fc4987 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -38,6 +38,7 @@ import android.support.v4.app.NotificationCompat; import android.support.v4.util.LongSparseArray; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Constants.NotificationIds; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; @@ -488,7 +489,7 @@ public class PassphraseCacheService extends Service { private void updateService() { if (mPassphraseCache.size() > 0) { - startForeground(Constants.Notification.PASSPHRASE_CACHE, getNotification()); + startForeground(NotificationIds.PASSPHRASE_CACHE, getNotification()); } else { // stop whole service if no cached passphrases remaining Timber.d("PassphraseCacheService: No passphrases remaining in memory, stopping service!"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java index b6df0f1db..f96107619 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java @@ -32,7 +32,7 @@ import android.support.v4.app.FragmentActivity; import android.support.v4.app.NotificationCompat; import android.view.ContextThemeWrapper; -import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Constants.NotificationIds; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -180,7 +180,7 @@ public class OrbotRequiredDialogActivity extends FragmentActivity public static void showOrbotRequiredNotification(Context context) { NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); if (manager != null) { - manager.notify(Constants.Notification.KEYSERVER_SYNC_FAIL_ORBOT, createOrbotNotification(context)); + manager.notify(NotificationIds.KEYSERVER_SYNC_FAIL_ORBOT, createOrbotNotification(context)); } } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c36650f1b..97d5aabf1 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -2024,4 +2024,8 @@ Found key data in clipboard! View + + Keyserver update + Updating keys… + Key %d / %d