Show notification during key sync

This commit is contained in:
Vincent Breitmoser 2018-06-13 18:20:41 +02:00
parent 40b7701f58
commit b854331daa
5 changed files with 97 additions and 10 deletions

View file

@ -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 {

View file

@ -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<ParcelableKeyRing> 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();

View file

@ -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!");

View file

@ -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));
}
}

View file

@ -2024,4 +2024,8 @@
<string name="snack_keylist_clipboard_title">Found key data in clipboard!</string>
<string name="snack_keylist_clipboard_action">View</string>
<string name="notify_channel_keysync">Keyserver update</string>
<string name="notify_title_keysync">Updating keys…</string>
<string name="notify_content_keysync">Key %d / %d</string>
</resources>