diff --git a/app/src/main/java/com/wireguard/android/Application.java b/app/src/main/java/com/wireguard/android/Application.java index ffecd4df..8dff8a54 100644 --- a/app/src/main/java/com/wireguard/android/Application.java +++ b/app/src/main/java/com/wireguard/android/Application.java @@ -19,7 +19,6 @@ import android.support.v7.app.AppCompatDelegate; import com.wireguard.android.backend.Backend; import com.wireguard.android.backend.GoBackend; import com.wireguard.android.backend.WgQuickBackend; -import com.wireguard.android.configStore.ConfigStore; import com.wireguard.android.configStore.FileConfigStore; import com.wireguard.android.model.TunnelManager; import com.wireguard.android.util.AsyncWorker; @@ -37,16 +36,14 @@ import java.io.File; import java.lang.ref.WeakReference; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Objects; -import java.util.concurrent.Executor; + +import java9.util.concurrent.CompletableFuture; @AcraCore(reportFormat = StringFormat.JSON, buildConfigClass = BuildConfig.class, - logcatArguments = { "-b", "all", "-d", "-v", "threadtime", "*:V" }, - excludeMatchingSharedPreferencesKeys={"last_used_tunnel", "enabled_configs"}) + logcatArguments = {"-b", "all", "-d", "-v", "threadtime", "*:V"}, + excludeMatchingSharedPreferencesKeys = {"last_used_tunnel", "enabled_configs"}) @AcraHttpSender(uri = "https://crashreport.zx2c4.com/android/report", basicAuthLogin = "6RCovLxEVCTXGiW5", basicAuthPassword = "O7I3sVa5ULVdiC51", @@ -59,10 +56,8 @@ public class Application extends android.app.Application { @SuppressWarnings("NullableProblems") private SharedPreferences sharedPreferences; @SuppressWarnings("NullableProblems") private ToolsInstaller toolsInstaller; @SuppressWarnings("NullableProblems") private TunnelManager tunnelManager; - @SuppressWarnings("NullableProblems") private Handler handler; @Nullable private Backend backend; - @Nullable private Collection haveBackendCallbacks = new ArrayList<>(); - private final Object haveBackendCallbacksLock = new Object(); + private final CompletableFuture futureBackend = new CompletableFuture<>(); public Application() { weakSelf = new WeakReference<>(this); @@ -114,43 +109,26 @@ public class Application extends android.app.Application { public static Backend getBackend() { final Application app = get(); - synchronized (app) { + synchronized (app.futureBackend) { if (app.backend == null) { + Backend backend = null; if (new File("/sys/module/wireguard").exists()) { try { app.rootShell.start(); - app.backend = new WgQuickBackend(app.getApplicationContext()); - } catch (final Exception ignored) { } - } - if (app.backend == null) - app.backend = new GoBackend(app.getApplicationContext()); - synchronized (app.haveBackendCallbacksLock) { - if (app.haveBackendCallbacks != null) { - for (final BackendCallback callback : app.haveBackendCallbacks) - app.handler.post(() -> callback.callback(app.backend)); - app.haveBackendCallbacks = null; + backend = new WgQuickBackend(app.getApplicationContext()); + } catch (final Exception ignored) { } } + if (backend == null) + backend = new GoBackend(app.getApplicationContext()); + app.backend = backend; } return app.backend; } } - @FunctionalInterface - public interface BackendCallback { - void callback(final Backend backend); - } - - public static void onHaveBackend(final BackendCallback callback) { - final Application app = get(); - synchronized (app.haveBackendCallbacksLock) { - if (app.haveBackendCallbacks == null) { - Objects.requireNonNull(app.backend, "Backend still null in onHaveBackend call"); - callback.callback(app.backend); - } else { - app.haveBackendCallbacks.add(callback); - } - } + public static CompletableFuture getBackendAsync() { + return get().futureBackend; } public static RootShell getRootShell() { @@ -173,11 +151,7 @@ public class Application extends android.app.Application { public void onCreate() { super.onCreate(); - handler = new Handler(Looper.getMainLooper()); - final Executor executor = AsyncTask.SERIAL_EXECUTOR; - final ConfigStore configStore = new FileConfigStore(getApplicationContext()); - - asyncWorker = new AsyncWorker(executor, handler); + asyncWorker = new AsyncWorker(AsyncTask.SERIAL_EXECUTOR, new Handler(Looper.getMainLooper())); rootShell = new RootShell(getApplicationContext()); toolsInstaller = new ToolsInstaller(getApplicationContext()); @@ -186,16 +160,14 @@ public class Application extends android.app.Application { sharedPreferences.getBoolean("dark_theme", false) ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); - tunnelManager = new TunnelManager(configStore); - asyncWorker.runAsync(Application::getBackend); + tunnelManager = new TunnelManager(new FileConfigStore(getApplicationContext())); tunnelManager.onCreate(); - onHaveBackend(backend -> { + asyncWorker.supplyAsync(Application::getBackend).thenAccept(backend -> { + futureBackend.complete(backend); ACRA.getErrorReporter().putCustomData("backend", backend.getClass().getSimpleName()); - getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> { - if (exception == null) - ACRA.getErrorReporter().putCustomData("backendVersion", version); - }); + asyncWorker.supplyAsync(backend::getVersion).thenAccept(version -> + ACRA.getErrorReporter().putCustomData("backendVersion", version)); }); } } diff --git a/app/src/main/java/com/wireguard/android/BootShutdownReceiver.java b/app/src/main/java/com/wireguard/android/BootShutdownReceiver.java index 3b9f852d..be6e729b 100644 --- a/app/src/main/java/com/wireguard/android/BootShutdownReceiver.java +++ b/app/src/main/java/com/wireguard/android/BootShutdownReceiver.java @@ -20,7 +20,7 @@ public class BootShutdownReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { - Application.onHaveBackend(backend -> { + Application.getBackendAsync().thenAccept(backend -> { if (!(backend instanceof WgQuickBackend)) return; final String action = intent.getAction(); diff --git a/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java b/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java index 066d377f..dc5a1a7c 100644 --- a/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java +++ b/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java @@ -99,7 +99,7 @@ public class SettingsActivity extends ThemeChangeAwareActivity { for (final Preference pref : wgQuickOnlyPrefs) pref.setVisible(false); final PreferenceScreen screen = getPreferenceScreen(); - Application.onHaveBackend(backend -> { + Application.getBackendAsync().thenAccept(backend -> { for (final Preference pref : wgQuickOnlyPrefs) { if (backend instanceof WgQuickBackend) pref.setVisible(true); diff --git a/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java b/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java index a5e28c81..f89ece75 100644 --- a/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java +++ b/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java @@ -94,7 +94,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC if (tunnel == null) return; - Application.onHaveBackend(backend -> { + Application.getBackendAsync().thenAccept(backend -> { if (backend instanceof GoBackend) { final Intent intent = GoBackend.VpnService.prepare(view.getContext()); if (intent != null) { diff --git a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java index 525396bc..25ace6e5 100644 --- a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java +++ b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java @@ -23,7 +23,7 @@ public class VersionPreference extends Preference { public VersionPreference(final Context context, final AttributeSet attrs) { super(context, attrs); - Application.onHaveBackend(backend -> { + Application.getBackendAsync().thenAccept(backend -> { versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypeName().toLowerCase()); Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> { versionSummary = exception == null