/* * Copyright © 2018 Samuel Holland * SPDX-License-Identifier: GPL-2.0-or-later */ package com.wireguard.android.util; import android.os.Handler; import com.wireguard.android.Application.ApplicationHandler; import com.wireguard.android.Application.ApplicationScope; import java.util.concurrent.Executor; import javax.inject.Inject; import java9.util.concurrent.CompletableFuture; import java9.util.concurrent.CompletionStage; /** * Helper class for running asynchronous tasks and ensuring they are completed on the main thread. */ @ApplicationScope public class AsyncWorker { private final Executor executor; private final Handler handler; @Inject AsyncWorker(final Executor executor, @ApplicationHandler final Handler handler) { this.executor = executor; this.handler = handler; } public CompletionStage runAsync(final AsyncRunnable runnable) { final CompletableFuture future = new CompletableFuture<>(); executor.execute(() -> { try { runnable.run(); handler.post(() -> future.complete(null)); } catch (final Throwable t) { handler.post(() -> future.completeExceptionally(t)); } }); return future; } public CompletionStage supplyAsync(final AsyncSupplier supplier) { final CompletableFuture future = new CompletableFuture<>(); executor.execute(() -> { try { final T result = supplier.get(); handler.post(() -> future.complete(result)); } catch (final Throwable t) { handler.post(() -> future.completeExceptionally(t)); } }); return future; } @FunctionalInterface public interface AsyncRunnable { void run() throws E; } @FunctionalInterface public interface AsyncSupplier { T get() throws E; } }