From 5247f2f3b4c987cc423ed182e5e782c36e942f24 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 30 May 2020 19:07:32 +0200 Subject: [PATCH] update workmanager --- OpenKeychain/build.gradle | 2 +- .../keychain/KeychainApplication.java | 41 ++++++++++++++++++- .../provider/TemporaryFileProvider.java | 20 ++++++--- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 628e8a8e3..7ac708127 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -63,7 +63,7 @@ dependencies { implementation project(':extern:bouncycastle:pg') // implementation project(':openkeychain:extern:bouncycastle:prov') - implementation 'androidx.work:work-runtime:2.2.0' + implementation 'androidx.work:work-runtime:2.3.4' // Unit tests in the local JVM with Robolectric // https://developer.android.com/training/testing/unit-testing/local-unit-tests.html diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 8febc38b9..845d0c055 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -18,23 +18,27 @@ package org.sufficientlysecure.keychain; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.security.Security; import java.util.HashMap; import android.accounts.Account; import android.accounts.AccountManager; +import android.annotation.SuppressLint; import android.app.Application; import android.content.Context; import android.graphics.Bitmap; -import androidx.annotation.Nullable; +import android.os.Build; import android.widget.Toast; +import androidx.annotation.Nullable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.analytics.AnalyticsManager; +import org.sufficientlysecure.keychain.keysync.KeyserverSyncManager; import org.sufficientlysecure.keychain.network.TlsCertificatePinning; import org.sufficientlysecure.keychain.provider.TemporaryFileProvider; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; -import org.sufficientlysecure.keychain.keysync.KeyserverSyncManager; import org.sufficientlysecure.keychain.util.PRNGFixes; import org.sufficientlysecure.keychain.util.Preferences; import timber.log.Timber; @@ -104,6 +108,11 @@ public class KeychainApplication extends Application { TlsCertificatePinning.addPinnedCertificate("pgp.mit.edu", getAssets(), "pgp.mit.edu.cer"); TlsCertificatePinning.addPinnedCertificate("keyserver.ubuntu.com", getAssets(), "LetsEncryptCA.cer"); + // only set up the rest on our main process + if (!BuildConfig.APPLICATION_ID.equals(getProcessName())) { + return; + } + KeyserverSyncManager.updateKeyserverSyncScheduleAsync(this, false); TemporaryFileProvider.scheduleCleanupImmediately(getApplicationContext()); @@ -161,4 +170,32 @@ public class KeychainApplication extends Application { public AnalyticsManager getAnalyticsManager() { return analyticsManager; } + + public static String getProcessName() { + if (Build.VERSION.SDK_INT >= 28) + return Application.getProcessName(); + + // Using the same technique as Application.getProcessName() for older devices + // Using reflection since ActivityThread is an internal API + + try { + @SuppressLint("PrivateApi") + Class activityThread = Class.forName("android.app.ActivityThread"); + + // Before API 18, the method was incorrectly named "currentPackageName", but it still returned the process name + // See https://github.com/aosp-mirror/platform_frameworks_base/commit/b57a50bd16ce25db441da5c1b63d48721bb90687 + String methodName = Build.VERSION.SDK_INT >= 18 ? "currentProcessName" : "currentPackageName"; + + Method getProcessName = activityThread.getDeclaredMethod(methodName); + return (String) getProcessName.invoke(null); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryFileProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryFileProvider.java index ee17e925c..37901984b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryFileProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryFileProvider.java @@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import android.app.Application; import android.content.ClipDescription; import android.content.ContentProvider; import android.content.ContentResolver; @@ -44,7 +45,9 @@ import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; import androidx.work.Worker; import androidx.work.WorkerParameters; +import org.sufficientlysecure.keychain.BuildConfig; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.KeychainApplication; import org.sufficientlysecure.keychain.util.DatabaseUtil; import timber.log.Timber; @@ -96,7 +99,7 @@ public class TemporaryFileProvider extends ContentProvider { contentValues.put(TemporaryFileColumns.COLUMN_TIME, System.currentTimeMillis()); Uri resultUri = contentResolver.insert(CONTENT_URI, contentValues); - scheduleCleanupAfterTtl(); + scheduleCleanupAfterTtl(context); return resultUri; } @@ -309,16 +312,23 @@ public class TemporaryFileProvider extends ContentProvider { return openFileHelper(uri, mode); } - public static void scheduleCleanupAfterTtl() { + public static void scheduleCleanupAfterTtl(Context context) { OneTimeWorkRequest cleanupWork = new OneTimeWorkRequest.Builder(CleanupWorker.class) .setInitialDelay(Constants.TEMPFILE_TTL, TimeUnit.MILLISECONDS).build(); - WorkManager.getInstance().enqueue(cleanupWork); + workManagerEnqueue(context, cleanupWork); } public static void scheduleCleanupImmediately(Context context) { OneTimeWorkRequest cleanupWork = new OneTimeWorkRequest.Builder(CleanupWorker.class).build(); - WorkManager workManager = WorkManager.getInstance(context); - workManager.enqueue(cleanupWork); + workManagerEnqueue(context, cleanupWork); + } + + private static void workManagerEnqueue(Context context, OneTimeWorkRequest cleanupWork) { + // work manager is only available on the main thread + if (!BuildConfig.APPLICATION_ID.equals(KeychainApplication.getProcessName())) { + return; + } + WorkManager.getInstance(context).enqueue(cleanupWork); } public static class CleanupWorker extends Worker {