@@ -56,6 +56,10 @@ public final class GoBackend implements Backend { | |||||
private static native int wgTurnOn(String ifName, int tunFd, String settings); | private static native int wgTurnOn(String ifName, int tunFd, String settings); | ||||
private static native String wgVersion(); | |||||
public static String getVersion() { return wgVersion(); } | |||||
@Override | @Override | ||||
public Config applyConfig(final Tunnel tunnel, final Config config) throws Exception { | public Config applyConfig(final Tunnel tunnel, final Config config) throws Exception { | ||||
if (tunnel.getState() == State.UP) { | if (tunnel.getState() == State.UP) { | ||||
@@ -0,0 +1,56 @@ | |||||
/* | |||||
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. 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); | |||||
} | |||||
} |
@@ -10,6 +10,7 @@ import android.content.Context; | |||||
import android.system.OsConstants; | import android.system.OsConstants; | ||||
import android.util.Log; | import android.util.Log; | ||||
import com.wireguard.android.Application; | |||||
import com.wireguard.android.Application.ApplicationContext; | import com.wireguard.android.Application.ApplicationContext; | ||||
import com.wireguard.android.Application.ApplicationScope; | import com.wireguard.android.Application.ApplicationScope; | ||||
import com.wireguard.android.util.RootShell.NoRootException; | 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.File; | ||||
import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.List; | import java.util.List; | ||||
import javax.inject.Inject; | import javax.inject.Inject; | ||||
import java9.util.concurrent.CompletionStage; | |||||
/** | /** | ||||
* Helper to install WireGuard tools to the system partition. | * Helper to install WireGuard tools to the system partition. | ||||
*/ | */ | ||||
@@ -52,6 +56,15 @@ public final class ToolsInstaller { | |||||
this.rootShell = rootShell; | this.rootShell = rootShell; | ||||
} | } | ||||
public CompletionStage<String> getVersion() { | |||||
return Application.getComponent().getAsyncWorker().supplyAsync(() -> { | |||||
final ArrayList<String> 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() { | private static File getInstallDir() { | ||||
final String path = System.getenv("PATH"); | final String path = System.getenv("PATH"); | ||||
if (path == null) | if (path == null) | ||||
@@ -74,5 +74,9 @@ | |||||
<string name="tunnel_create_success">Successfully created tunnel “%s”</string> | <string name="tunnel_create_success">Successfully created tunnel “%s”</string> | ||||
<string name="tunnel_rename_error">Unable to rename tunnel: %s</string> | <string name="tunnel_rename_error">Unable to rename tunnel: %s</string> | ||||
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string> | <string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string> | ||||
<string name="version_title">WireGuard for Android v%s"</string> | |||||
<string name="version_kernel_summary">Using kernel module implementation v%s</string> | |||||
<string name="version_kernel_unknown_summary">Using unknown kernel module implementation</string> | |||||
<string name="version_userspace_summary">Using Go userspace implementation v%s</string> | |||||
<string name="zip_exporter_title">Export tunnels to zip file</string> | <string name="zip_exporter_title">Export tunnels to zip file</string> | ||||
</resources> | </resources> |
@@ -13,4 +13,5 @@ | |||||
android:summaryOn="@string/dark_theme_summary_on" | android:summaryOn="@string/dark_theme_summary_on" | ||||
android:summaryOff="@string/dark_theme_summary_off" | android:summaryOff="@string/dark_theme_summary_off" | ||||
android:title="@string/dark_theme_title" /> | android:title="@string/dark_theme_title" /> | ||||
<com.wireguard.android.preference.VersionPreference /> | |||||
</PreferenceScreen> | </PreferenceScreen> |
@@ -160,4 +160,9 @@ func wgGetSocketV6(tunnelHandle int32) int32 { | |||||
return fd | return fd | ||||
} | } | ||||
//export wgVersion | |||||
func wgVersion() string { | |||||
return WireGuardGoVersion | |||||
} | |||||
func main() {} | func main() {} |
@@ -4,12 +4,15 @@ | |||||
*/ | */ | ||||
#include <jni.h> | #include <jni.h> | ||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
struct go_string { const char *str; long n; }; | struct go_string { const char *str; long n; }; | ||||
extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings); | extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings); | ||||
extern void wgTurnOff(int handle); | extern void wgTurnOff(int handle); | ||||
extern int wgGetSocketV4(int handle); | extern int wgGetSocketV4(int handle); | ||||
extern int wgGetSocketV6(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) | 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); | 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; | |||||
} |