diff --git a/app/src/main/java/com/wireguard/android/backend/GoBackend.java b/app/src/main/java/com/wireguard/android/backend/GoBackend.java index 4963f759..e1accdad 100644 --- a/app/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/app/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -56,6 +56,10 @@ public final class GoBackend implements Backend { private static native int wgTurnOn(String ifName, int tunFd, String settings); + private static native String wgVersion(); + + public static String getVersion() { return wgVersion(); } + @Override public Config applyConfig(final Tunnel tunnel, final Config config) throws Exception { if (tunnel.getState() == State.UP) { diff --git a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java new file mode 100644 index 00000000..c0fb986b --- /dev/null +++ b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java @@ -0,0 +1,56 @@ +/* + * Copyright © 2018 Jason A. Donenfeld . All Rights Reserved. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +package com.wireguard.android.preference; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v7.preference.Preference; +import android.util.AttributeSet; + +import com.wireguard.android.Application; +import com.wireguard.android.BuildConfig; +import com.wireguard.android.R; +import com.wireguard.android.backend.GoBackend; +import com.wireguard.android.backend.WgQuickBackend; + +public class VersionPreference extends Preference { + private String versionSummary; + + public VersionPreference(final Context context, final AttributeSet attrs) { + super(context, attrs); + + if (Application.getComponent().getBackendType() == GoBackend.class) { + versionSummary = getContext().getString(R.string.version_userspace_summary, GoBackend.getVersion()); + } else if (Application.getComponent().getBackendType() == WgQuickBackend.class) { + Application.getComponent().getToolsInstaller().getVersion().whenComplete((version, exception) -> { + if (exception == null) + versionSummary = getContext().getString(R.string.version_kernel_summary, version); + else + versionSummary = getContext().getString(R.string.version_kernel_unknown_summary); + notifyChanged(); + }); + } + } + + @Override + public CharSequence getSummary() { + return versionSummary; + } + + @Override + public CharSequence getTitle() { + return getContext().getString(R.string.version_title, BuildConfig.VERSION_NAME); + } + + @Override + protected void onClick() { + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://www.wireguard.com/")); + getContext().startActivity(intent); + } + +} diff --git a/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java b/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java index fc2897b3..f101bb32 100644 --- a/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java +++ b/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java @@ -10,6 +10,7 @@ import android.content.Context; import android.system.OsConstants; import android.util.Log; +import com.wireguard.android.Application; import com.wireguard.android.Application.ApplicationContext; import com.wireguard.android.Application.ApplicationScope; import com.wireguard.android.util.RootShell.NoRootException; @@ -17,11 +18,14 @@ import com.wireguard.android.util.RootShell.NoRootException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.inject.Inject; +import java9.util.concurrent.CompletionStage; + /** * Helper to install WireGuard tools to the system partition. */ @@ -52,6 +56,15 @@ public final class ToolsInstaller { this.rootShell = rootShell; } + public CompletionStage getVersion() { + return Application.getComponent().getAsyncWorker().supplyAsync(() -> { + final ArrayList output = new ArrayList<>(); + if (rootShell.run(output, "cat /sys/module/wireguard/version") != 0 || output.isEmpty()) + throw new RuntimeException("Unable to determine kernel module version"); + return output.get(0); + }); + } + private static File getInstallDir() { final String path = System.getenv("PATH"); if (path == null) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 408de6b1..91e3fb0a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,5 +74,9 @@ Successfully created tunnel “%s” Unable to rename tunnel: %s Successfully renamed tunnel to “%s” + WireGuard for Android v%s" + Using kernel module implementation v%s + Using unknown kernel module implementation + Using Go userspace implementation v%s Export tunnels to zip file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index acec919c..78483f6b 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -13,4 +13,5 @@ android:summaryOn="@string/dark_theme_summary_on" android:summaryOff="@string/dark_theme_summary_off" android:title="@string/dark_theme_title" /> + diff --git a/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/api-android.go b/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/api-android.go index f5dae966..19063eec 100644 --- a/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/api-android.go +++ b/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/api-android.go @@ -160,4 +160,9 @@ func wgGetSocketV6(tunnelHandle int32) int32 { return fd } +//export wgVersion +func wgVersion() string { + return WireGuardGoVersion +} + func main() {} diff --git a/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/jni.c b/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/jni.c index a0f3d0ba..acb2d728 100644 --- a/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/jni.c +++ b/app/tools/libwg-go/src/git.zx2c4.com/wireguard-go/jni.c @@ -4,12 +4,15 @@ */ #include +#include +#include struct go_string { const char *str; long n; }; extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings); extern void wgTurnOff(int handle); extern int wgGetSocketV4(int handle); extern int wgGetSocketV6(int handle); +extern struct go_string wgVersion(); JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOn(JNIEnv *env, jclass c, jstring ifname, jint tun_fd, jstring settings) { @@ -43,3 +46,17 @@ JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgGetSocketV { return wgGetSocketV6(handle); } + +JNIEXPORT jstring JNICALL Java_com_wireguard_android_backend_GoBackend_wgVersion(JNIEnv *env, jclass c) +{ + struct go_string s = wgVersion(); + char *cstr = malloc(s.n + 1); + if (!cstr) + return NULL; + jstring ret; + memcpy(cstr, s.str, s.n); + cstr[s.n] = '\0'; + ret = (*env)->NewStringUTF(env, cstr); + free(cstr); + return ret; +}