Make thread related utility methods available for use in all modules.

This commit is contained in:
Cody Henthorne
2021-03-01 15:44:33 -05:00
parent 38caf1e2b7
commit dc9b8169c0
47 changed files with 228 additions and 224 deletions

View File

@@ -7,6 +7,8 @@ import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import org.signal.core.util.ThreadUtil;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -22,7 +24,7 @@ public final class AppForegroundObserver {
@MainThread
public void begin() {
Util.assertMainThread();
ThreadUtil.assertMainThread();
ProcessLifecycleOwner.get().getLifecycle().addObserver(new DefaultLifecycleObserver() {
@Override

View File

@@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.util;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.ThreadUtil;
public final class AsynchronousCallback {
/**
@@ -51,12 +53,12 @@ public final class AsynchronousCallback {
return new WorkerThread<R, E>() {
@Override
public void onComplete(@Nullable R result) {
Util.runOnMain(() -> MainThread.this.onComplete(result));
ThreadUtil.runOnMain(() -> MainThread.this.onComplete(result));
}
@Override
public void onError(@Nullable E error) {
Util.runOnMain(() -> MainThread.this.onError(error));
ThreadUtil.runOnMain(() -> MainThread.this.onError(error));
}
};
}

View File

@@ -20,6 +20,7 @@ import androidx.exifinterface.media.ExifInterface;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.MediaConstraints;
@@ -410,7 +411,7 @@ public class BitmapUtil {
}
};
Util.runOnMain(runnable);
ThreadUtil.runOnMain(runnable);
synchronized (result) {
while (!created.get()) Util.wait(result, 0);

View File

@@ -12,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
@@ -124,7 +125,7 @@ public class CachedInflater {
}
AsyncLayoutInflater.OnInflateFinishedListener onInflateFinishedListener = (view, resId, p) -> {
Util.assertMainThread();
ThreadUtil.assertMainThread();
if (enqueueTime < lastClearTime) {
Log.d(TAG, "Prefetch is no longer valid. Ignoring.");
return;

View File

@@ -6,6 +6,7 @@ import androidx.annotation.WorkerThread;
import androidx.lifecycle.Observer;
import org.conscrypt.Conscrypt;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
@@ -16,10 +17,6 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.internal.configuration.SignalProxy;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -97,14 +94,14 @@ public final class SignalProxyUtil {
}
};
Util.runOnMainSync(() -> ApplicationDependencies.getPipeListener().getState().observeForever(observer));
ThreadUtil.runOnMainSync(() -> ApplicationDependencies.getPipeListener().getState().observeForever(observer));
try {
latch.await(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Log.w(TAG, "Interrupted!", e);
} finally {
Util.runOnMainSync(() -> ApplicationDependencies.getPipeListener().getState().removeObserver(observer));
ThreadUtil.runOnMainSync(() -> ApplicationDependencies.getPipeListener().getState().removeObserver(observer));
}
return success.get();

View File

@@ -27,8 +27,6 @@ import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Looper;
import android.provider.Telephony;
import android.telephony.TelephonyManager;
import android.text.Spannable;
@@ -47,7 +45,6 @@ import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import org.signal.core.util.LinkedBlockingLifoQueue;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.components.ComposeText;
@@ -66,9 +63,6 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Util {
@@ -76,8 +70,6 @@ public class Util {
private static final long BUILD_LIFESPAN = TimeUnit.DAYS.toMillis(90);
private static volatile Handler handler;
public static <T> List<T> asList(T... elements) {
List<T> result = new LinkedList<>();
Collections.addAll(result, elements);
@@ -148,17 +140,6 @@ public class Util {
return out.toString();
}
public static ExecutorService newSingleThreadedLifoExecutor() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingLifoQueue<Runnable>());
executor.execute(() -> {
// Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
});
return executor;
}
public static boolean isEmpty(EncodedStringValue[] value) {
return value == null || value.length == 0;
}
@@ -422,59 +403,6 @@ public class Util {
return (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) || OutgoingLegacyMmsConnection.isConnectionPossible(context);
}
public static boolean isMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
public static void assertMainThread() {
if (!isMainThread()) {
throw new AssertionError("Must run on main thread.");
}
}
public static void assertNotMainThread() {
if (isMainThread()) {
throw new AssertionError("Cannot run on main thread.");
}
}
public static void postToMain(final @NonNull Runnable runnable) {
getHandler().post(runnable);
}
public static void runOnMain(final @NonNull Runnable runnable) {
if (isMainThread()) runnable.run();
else getHandler().post(runnable);
}
public static void runOnMainDelayed(final @NonNull Runnable runnable, long delayMillis) {
getHandler().postDelayed(runnable, delayMillis);
}
public static void cancelRunnableOnMain(@NonNull Runnable runnable) {
getHandler().removeCallbacks(runnable);
}
public static void runOnMainSync(final @NonNull Runnable runnable) {
if (isMainThread()) {
runnable.run();
} else {
final CountDownLatch sync = new CountDownLatch(1);
runOnMain(() -> {
try {
runnable.run();
} finally {
sync.countDown();
}
});
try {
sync.await();
} catch (InterruptedException ie) {
throw new AssertionError(ie);
}
}
}
public static <T> T getRandomElement(T[] elements) {
return elements[new SecureRandom().nextInt(elements.length)];
}
@@ -551,29 +479,10 @@ public class Util {
return MemoryUnitFormat.formatBytes(sizeBytes);
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
public static void copyToClipboard(@NonNull Context context, @NonNull String text) {
ServiceUtil.getClipboardManager(context).setPrimaryClip(ClipData.newPlainText("text", text));
}
private static Handler getHandler() {
if (handler == null) {
synchronized (Util.class) {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
}
}
return handler;
}
@SafeVarargs
public static <T> List<T> concatenatedList(Collection <T>... items) {
final List<T> concat = new ArrayList<>(Stream.of(items).reduce(0, (sum, list) -> sum + list.size()));

View File

@@ -5,8 +5,8 @@ import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.Util;
import java.util.concurrent.Executor;
@@ -28,7 +28,7 @@ public class SimpleTask {
final E result = backgroundTask.run();
if (isValid(lifecycle)) {
Util.runOnMain(() -> {
ThreadUtil.runOnMain(() -> {
if (isValid(lifecycle)) {
foregroundTask.run(result);
}
@@ -52,7 +52,7 @@ public class SimpleTask {
public static <E> void run(@NonNull Executor executor, @NonNull BackgroundTask<E> backgroundTask, @NonNull ForegroundTask<E> foregroundTask) {
executor.execute(() -> {
final E result = backgroundTask.run();
Util.runOnMain(() -> foregroundTask.run(result));
ThreadUtil.runOnMain(() -> foregroundTask.run(result));
});
}

View File

@@ -7,9 +7,9 @@ import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.Util;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
@@ -66,18 +66,18 @@ public final class SimpleProgressDialog {
dialogAtomicReference.set(show(context));
};
Util.runOnMainDelayed(showRunnable, delayMs);
ThreadUtil.runOnMainDelayed(showRunnable, delayMs);
return () -> {
Util.cancelRunnableOnMain(showRunnable);
Util.runOnMain(() -> {
ThreadUtil.cancelRunnableOnMain(showRunnable);
ThreadUtil.runOnMain(() -> {
AlertDialog alertDialog = dialogAtomicReference.getAndSet(null);
if (alertDialog != null) {
long beenShowingForMs = System.currentTimeMillis() - shownAt.get();
long remainingTimeMs = minimumShowTimeMs - beenShowingForMs;
if (remainingTimeMs > 0) {
Util.runOnMainDelayed(alertDialog::dismiss, remainingTimeMs);
ThreadUtil.runOnMainDelayed(alertDialog::dismiss, remainingTimeMs);
} else {
alertDialog.dismiss();
}