Application: use proper completablefuture for backend
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
7d438e9dbc
commit
62d8beff96
@ -19,7 +19,6 @@ import android.support.v7.app.AppCompatDelegate;
|
|||||||
import com.wireguard.android.backend.Backend;
|
import com.wireguard.android.backend.Backend;
|
||||||
import com.wireguard.android.backend.GoBackend;
|
import com.wireguard.android.backend.GoBackend;
|
||||||
import com.wireguard.android.backend.WgQuickBackend;
|
import com.wireguard.android.backend.WgQuickBackend;
|
||||||
import com.wireguard.android.configStore.ConfigStore;
|
|
||||||
import com.wireguard.android.configStore.FileConfigStore;
|
import com.wireguard.android.configStore.FileConfigStore;
|
||||||
import com.wireguard.android.model.TunnelManager;
|
import com.wireguard.android.model.TunnelManager;
|
||||||
import com.wireguard.android.util.AsyncWorker;
|
import com.wireguard.android.util.AsyncWorker;
|
||||||
@ -37,16 +36,14 @@ import java.io.File;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java9.util.concurrent.CompletableFuture;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
|
|
||||||
@AcraCore(reportFormat = StringFormat.JSON,
|
@AcraCore(reportFormat = StringFormat.JSON,
|
||||||
buildConfigClass = BuildConfig.class,
|
buildConfigClass = BuildConfig.class,
|
||||||
logcatArguments = { "-b", "all", "-d", "-v", "threadtime", "*:V" },
|
logcatArguments = {"-b", "all", "-d", "-v", "threadtime", "*:V"},
|
||||||
excludeMatchingSharedPreferencesKeys={"last_used_tunnel", "enabled_configs"})
|
excludeMatchingSharedPreferencesKeys = {"last_used_tunnel", "enabled_configs"})
|
||||||
@AcraHttpSender(uri = "https://crashreport.zx2c4.com/android/report",
|
@AcraHttpSender(uri = "https://crashreport.zx2c4.com/android/report",
|
||||||
basicAuthLogin = "6RCovLxEVCTXGiW5",
|
basicAuthLogin = "6RCovLxEVCTXGiW5",
|
||||||
basicAuthPassword = "O7I3sVa5ULVdiC51",
|
basicAuthPassword = "O7I3sVa5ULVdiC51",
|
||||||
@ -59,10 +56,8 @@ public class Application extends android.app.Application {
|
|||||||
@SuppressWarnings("NullableProblems") private SharedPreferences sharedPreferences;
|
@SuppressWarnings("NullableProblems") private SharedPreferences sharedPreferences;
|
||||||
@SuppressWarnings("NullableProblems") private ToolsInstaller toolsInstaller;
|
@SuppressWarnings("NullableProblems") private ToolsInstaller toolsInstaller;
|
||||||
@SuppressWarnings("NullableProblems") private TunnelManager tunnelManager;
|
@SuppressWarnings("NullableProblems") private TunnelManager tunnelManager;
|
||||||
@SuppressWarnings("NullableProblems") private Handler handler;
|
|
||||||
@Nullable private Backend backend;
|
@Nullable private Backend backend;
|
||||||
@Nullable private Collection<BackendCallback> haveBackendCallbacks = new ArrayList<>();
|
private final CompletableFuture<Backend> futureBackend = new CompletableFuture<>();
|
||||||
private final Object haveBackendCallbacksLock = new Object();
|
|
||||||
|
|
||||||
public Application() {
|
public Application() {
|
||||||
weakSelf = new WeakReference<>(this);
|
weakSelf = new WeakReference<>(this);
|
||||||
@ -114,43 +109,26 @@ public class Application extends android.app.Application {
|
|||||||
|
|
||||||
public static Backend getBackend() {
|
public static Backend getBackend() {
|
||||||
final Application app = get();
|
final Application app = get();
|
||||||
synchronized (app) {
|
synchronized (app.futureBackend) {
|
||||||
if (app.backend == null) {
|
if (app.backend == null) {
|
||||||
|
Backend backend = null;
|
||||||
if (new File("/sys/module/wireguard").exists()) {
|
if (new File("/sys/module/wireguard").exists()) {
|
||||||
try {
|
try {
|
||||||
app.rootShell.start();
|
app.rootShell.start();
|
||||||
app.backend = new WgQuickBackend(app.getApplicationContext());
|
backend = new WgQuickBackend(app.getApplicationContext());
|
||||||
} catch (final Exception ignored) { }
|
} 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (backend == null)
|
||||||
|
backend = new GoBackend(app.getApplicationContext());
|
||||||
|
app.backend = backend;
|
||||||
}
|
}
|
||||||
return app.backend;
|
return app.backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
public static CompletableFuture<Backend> getBackendAsync() {
|
||||||
public interface BackendCallback {
|
return get().futureBackend;
|
||||||
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 RootShell getRootShell() {
|
public static RootShell getRootShell() {
|
||||||
@ -173,11 +151,7 @@ public class Application extends android.app.Application {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
handler = new Handler(Looper.getMainLooper());
|
asyncWorker = new AsyncWorker(AsyncTask.SERIAL_EXECUTOR, new Handler(Looper.getMainLooper()));
|
||||||
final Executor executor = AsyncTask.SERIAL_EXECUTOR;
|
|
||||||
final ConfigStore configStore = new FileConfigStore(getApplicationContext());
|
|
||||||
|
|
||||||
asyncWorker = new AsyncWorker(executor, handler);
|
|
||||||
rootShell = new RootShell(getApplicationContext());
|
rootShell = new RootShell(getApplicationContext());
|
||||||
toolsInstaller = new ToolsInstaller(getApplicationContext());
|
toolsInstaller = new ToolsInstaller(getApplicationContext());
|
||||||
|
|
||||||
@ -186,16 +160,14 @@ public class Application extends android.app.Application {
|
|||||||
sharedPreferences.getBoolean("dark_theme", false) ?
|
sharedPreferences.getBoolean("dark_theme", false) ?
|
||||||
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
|
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
|
||||||
|
|
||||||
tunnelManager = new TunnelManager(configStore);
|
tunnelManager = new TunnelManager(new FileConfigStore(getApplicationContext()));
|
||||||
asyncWorker.runAsync(Application::getBackend);
|
|
||||||
tunnelManager.onCreate();
|
tunnelManager.onCreate();
|
||||||
|
|
||||||
onHaveBackend(backend -> {
|
asyncWorker.supplyAsync(Application::getBackend).thenAccept(backend -> {
|
||||||
|
futureBackend.complete(backend);
|
||||||
ACRA.getErrorReporter().putCustomData("backend", backend.getClass().getSimpleName());
|
ACRA.getErrorReporter().putCustomData("backend", backend.getClass().getSimpleName());
|
||||||
getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
|
asyncWorker.supplyAsync(backend::getVersion).thenAccept(version ->
|
||||||
if (exception == null)
|
ACRA.getErrorReporter().putCustomData("backendVersion", version));
|
||||||
ACRA.getErrorReporter().putCustomData("backendVersion", version);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public class BootShutdownReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
Application.onHaveBackend(backend -> {
|
Application.getBackendAsync().thenAccept(backend -> {
|
||||||
if (!(backend instanceof WgQuickBackend))
|
if (!(backend instanceof WgQuickBackend))
|
||||||
return;
|
return;
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
|
@ -99,7 +99,7 @@ public class SettingsActivity extends ThemeChangeAwareActivity {
|
|||||||
for (final Preference pref : wgQuickOnlyPrefs)
|
for (final Preference pref : wgQuickOnlyPrefs)
|
||||||
pref.setVisible(false);
|
pref.setVisible(false);
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
Application.onHaveBackend(backend -> {
|
Application.getBackendAsync().thenAccept(backend -> {
|
||||||
for (final Preference pref : wgQuickOnlyPrefs) {
|
for (final Preference pref : wgQuickOnlyPrefs) {
|
||||||
if (backend instanceof WgQuickBackend)
|
if (backend instanceof WgQuickBackend)
|
||||||
pref.setVisible(true);
|
pref.setVisible(true);
|
||||||
|
@ -94,7 +94,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
|
|||||||
if (tunnel == null)
|
if (tunnel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Application.onHaveBackend(backend -> {
|
Application.getBackendAsync().thenAccept(backend -> {
|
||||||
if (backend instanceof GoBackend) {
|
if (backend instanceof GoBackend) {
|
||||||
final Intent intent = GoBackend.VpnService.prepare(view.getContext());
|
final Intent intent = GoBackend.VpnService.prepare(view.getContext());
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
|
@ -23,7 +23,7 @@ public class VersionPreference extends Preference {
|
|||||||
public VersionPreference(final Context context, final AttributeSet attrs) {
|
public VersionPreference(final Context context, final AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
Application.onHaveBackend(backend -> {
|
Application.getBackendAsync().thenAccept(backend -> {
|
||||||
versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypeName().toLowerCase());
|
versionSummary = getContext().getString(R.string.version_summary_checking, backend.getTypeName().toLowerCase());
|
||||||
Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
|
Application.getAsyncWorker().supplyAsync(backend::getVersion).whenComplete((version, exception) -> {
|
||||||
versionSummary = exception == null
|
versionSummary = exception == null
|
||||||
|
Loading…
Reference in New Issue
Block a user