Compare commits

...

32 Commits

Author SHA1 Message Date
Jason A. Donenfeld 09b75c2bd3 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2026-01-02 03:37:18 +01:00
Jason A. Donenfeld 2a01764282 tunnel: also bump the minsdk of this module
Fixes: 3b6ab660 ("ui: raise min SDK to 24")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2026-01-02 03:34:42 +01:00
Jason A. Donenfeld 3f30378c73 tunnel: newIncompleteFuture requires API 31
Fixes: 3b6ab660 ("ui: raise min SDK to 24")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2026-01-02 03:33:27 +01:00
Jason A. Donenfeld a494c62bd9 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-12-31 13:11:08 +01:00
Jason A. Donenfeld 743b28bb85 Updater: don't compile in updater when it can't be used
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-12-31 13:06:45 +01:00
Jason A. Donenfeld 1c0b211bd6 LogViewerActivity: remove unnecessary ?.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-12-31 12:23:59 +01:00
Jason A. Donenfeld 5e88cd24c5 build: upgrade all dependencies
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-12-31 12:15:42 +01:00
Harsh Shandilya 3b6ab660a9 ui: raise min SDK to 24
The difference between the usage of 21 and 24 is not big enough to hold
on to all the baggage from API 21

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-10-20 18:22:36 +02:00
Brandon T 0d18e478ca tunnel: add isAlwaysOn and isLockdownEnabled
Signed-off-by: Brandon T <JustBrandonT@gmail.com>
[Harsh: fix build and Javadoc errors]
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-10-20 18:22:36 +02:00
Anthony Ryan 89c0bb6c7a ui: losslessly optimize launcher icons
Using Efficient-Comprression-Tool we can reduce image size  by 37.59KB (27%)
with no visual change.

      compressed      │     uncompressed      │
──────────┬───────────┼───────────┬───────────┤
 size     │ diff      │ size      │ diff      │ path
──────────┼───────────┼───────────┼───────────┼───────────────────────────────────────────────
 75.2 KiB │ +75.2 KiB │       0 B │       0 B │ +
 15.8 KiB │  -6.7 KiB │  15.7 KiB │  -6.7 KiB │ ∆ res/mipmap-xxxhdpi-v4/ic_launcher.png
 20.4 KiB │  -6.3 KiB │  20.3 KiB │  -6.3 KiB │ ∆ res/mipmap-xxxhdpi-v4/ic_launcher_round.png
  8.6 KiB │  -6.2 KiB │   8.4 KiB │  -6.2 KiB │ ∆ res/mipmap-xhdpi-v4/banner.png
 11.6 KiB │  -4.3 KiB │  11.5 KiB │  -4.3 KiB │ ∆ res/mipmap-xxhdpi-v4/ic_launcher.png
 15.2 KiB │    -4 KiB │  15.1 KiB │    -4 KiB │ ∆ res/mipmap-xxhdpi-v4/ic_launcher_round.png
  6.2 KiB │  -2.6 KiB │   6.1 KiB │  -2.6 KiB │ ∆ res/mipmap-xhdpi-v4/ic_launcher.png
  7.9 KiB │  -2.5 KiB │   7.8 KiB │  -2.5 KiB │ ∆ res/mipmap-xhdpi-v4/ic_launcher_round.png
    5 KiB │  -1.7 KiB │   4.9 KiB │  -1.7 KiB │ ∆ res/mipmap-hdpi-v4/ic_launcher.png
    6 KiB │  -1.5 KiB │   5.8 KiB │  -1.5 KiB │ ∆ res/mipmap-hdpi-v4/ic_launcher_round.png
  2.7 KiB │  -1,002 B │   2.5 KiB │    -996 B │ ∆ res/mipmap-mdpi-v4/ic_launcher.png
  3.2 KiB │    -918 B │   3.1 KiB │    -918 B │ ∆ res/mipmap-mdpi-v4/ic_launcher_round.png
──────────┼───────────┼───────────┼───────────┼───────────────────────────────────────────────
  178 KiB │ +37.6 KiB │ 101.1 KiB │ -37.6 KiB │ (total)

[0]: https://github.com/JakeWharton/diffuse/

Signed-off-by: Anthony Ryan <anthonyryan1@gmail.com>
[Harsh: comparing APKs with Diffuse[0] shows modest but non-zero size savings]
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2025-10-20 18:22:36 +02:00
Harsh Shandilya 705ebdb19c build: upgrade all dependencies
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-10-20 18:22:36 +02:00
Harsh Shandilya b5411b8c57 gradle: upgrade to 9.1.0
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-10-20 18:22:36 +02:00
Harsh Shandilya 9438b9d7f4 build(tunnel): update publishing setup for OSSRH deprecation
The newly added zipReleasePublication task will generate a ZIP file at tunnel/build/distributions/tunnel-$VERSION-maven.zip
that can be uploaded to https://central.sonatype.com/publishing.

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-10-20 18:22:36 +02:00
Jason A. Donenfeld f0b45d50f3 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-31 04:22:08 +02:00
Jason A. Donenfeld cb216c6ec6 QrCodeFromFileScanner: more efficiently downscale images and release memory
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-31 04:22:06 +02:00
Jason A. Donenfeld d45b1ea9a7 QrCodeFromFileScanner: catch OOM errors
OutOfMemoryError is an Error which is a Throwable, but it isn't an
exception. Try to catch it for downscaling by catching all Throwables.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-31 03:47:10 +02:00
Jason A. Donenfeld f9764e9592 gradle: bump dependencies
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-31 03:43:04 +02:00
Jason A. Donenfeld 6414de156c QuickTileService: wait for tunnels to load
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-28 03:56:51 +02:00
Jason A. Donenfeld fa989fe58e QuickTileService: handle onClick in applicationScope
This helps with the case where the TunnelManager is still loading.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-28 03:49:37 +02:00
Jason A. Donenfeld 1310a513d8 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-23 04:19:29 +02:00
Jason A. Donenfeld 90395232b0 TvMainActivity: link to cx file explorer
Google requires us to link to a specific file manager. We can't just
open the app store. They keep rejecting the app otherwise. Annoying.

Also, due to Android TV bugs, we also can't link to a prefilled search
query of "file manager". Instead we must link to an actual file manager.

Unfortunately, none of the open source file manager apps both support
the TV interface and can act as a file chooser. So instead we pick what
looks like the only decent one that doesn't have any in app purchases.
Ugh. I don't like doing this. It's not an endorsement. I don't know much
about who makes these. But what choice do we have?

So doing this for now. Maybe we'll find some better solution or apply to
be a file manager ourselves in the future.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-23 04:16:41 +02:00
Jason A. Donenfeld b9969891b8 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-22 01:46:37 +02:00
Jason A. Donenfeld 559112998f tools: bump to wireguard-go 0.0.20250522 for major regression
Things were broken on kernels [4.19, 5.12).

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-22 01:46:10 +02:00
Jason A. Donenfeld e12e658408 DonatePreferences: use toUri() extension
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-21 01:48:42 +02:00
Jason A. Donenfeld a57ca57e6c tools: align to 16k
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-21 01:46:01 +02:00
Jason A. Donenfeld f3f30030b9 tools: bump wireguard-tools to 1.0.20250521
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-21 01:35:38 +02:00
Jason A. Donenfeld c417bb8d7c version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 18:14:43 +02:00
Jason A. Donenfeld 567fd6ae96 gradle: update to agp 8.10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 18:11:00 +02:00
Jason A. Donenfeld 2c223fb68c MainActivity: don't reuse id names across layouts
This causes problems on foldables.

Reported-by: Josh Dague <josh3736@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 17:57:39 +02:00
Jason A. Donenfeld 0ea6cee192 global: add missing xml copyright and opening tag
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 17:40:03 +02:00
Jason A. Donenfeld 0295abd808 global: update copyright notices
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 17:31:02 +02:00
Jason A. Donenfeld 0350b801b6 TunnelCreatorActivity: use proper xml for layout
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2025-05-19 17:26:38 +02:00
171 changed files with 528 additions and 352 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
wireguardVersionCode=512
wireguardVersionName=1.0.20250516
wireguardVersionCode=518
wireguardVersionName=1.0.20260102
wireguardPackageName=com.wireguard.android
# When configured, Gradle will run in incubating parallel mode.
+10 -10
View File
@@ -1,25 +1,25 @@
[versions]
agp = "8.9.3"
kotlin = "2.1.20"
agp = "8.13.2"
kotlin = "2.3.0"
[libraries]
androidx-activity-ktx = "androidx.activity:activity-ktx:1.10.1"
androidx-activity-ktx = "androidx.activity:activity-ktx:1.12.2"
androidx-annotation = "androidx.annotation:annotation:1.9.1"
androidx-appcompat = "androidx.appcompat:appcompat:1.7.0"
androidx-appcompat = "androidx.appcompat:appcompat:1.7.1"
androidx-biometric = "androidx.biometric:biometric:1.1.0"
androidx-collection = "androidx.collection:collection:1.5.0"
androidx-constraintlayout = "androidx.constraintlayout:constraintlayout:2.2.1"
androidx-coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:1.3.0"
androidx-core-ktx = "androidx.core:core-ktx:1.16.0"
androidx-datastore-preferences = "androidx.datastore:datastore-preferences:1.1.6"
androidx-fragment-ktx = "androidx.fragment:fragment-ktx:1.8.6"
androidx-lifecycle-runtime-ktx = "androidx.lifecycle:lifecycle-runtime-ktx:2.9.0"
androidx-core-ktx = "androidx.core:core-ktx:1.17.0"
androidx-datastore-preferences = "androidx.datastore:datastore-preferences:1.2.0"
androidx-fragment-ktx = "androidx.fragment:fragment-ktx:1.8.9"
androidx-lifecycle-runtime-ktx = "androidx.lifecycle:lifecycle-runtime-ktx:2.10.0"
androidx-preference-ktx = "androidx.preference:preference-ktx:1.2.1"
desugarJdkLibs = "com.android.tools:desugar_jdk_libs:2.1.5"
google-material = "com.google.android.material:material:1.12.0"
google-material = "com.google.android.material:material:1.13.0"
jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
junit = "junit:junit:4.13.2"
kotlinx-coroutines-android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
kotlinx-coroutines-android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2"
zxing-android-embedded = "com.journeyapps:zxing-android-embedded:4.3.0"
[plugins]
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=61ad310d3c7d3e5da131b76bbf22b5a4c0786e9d892dae8c1658d4b484de3caa
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+4 -8
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -115,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -173,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -206,15 +203,14 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
+22 -7
View File
@@ -1,6 +1,7 @@
@file:Suppress("UnstableApiUsage")
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.gradle.api.tasks.bundling.Zip
val pkg: String = providers.gradleProperty("wireguardPackageName").get()
@@ -18,7 +19,7 @@ android {
}
namespace = "${pkg}.tunnel"
defaultConfig {
minSdk = 21
minSdk = 24
}
externalNativeBuild {
cmake {
@@ -34,6 +35,7 @@ android {
cmake {
targets("libwg-go.so", "libwg.so", "libwg-quick.so")
arguments("-DGRADLE_USER_HOME=${project.gradle.gradleUserHomeDir}")
arguments("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
}
}
}
@@ -112,16 +114,29 @@ publishing {
}
repositories {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = providers.environmentVariable("SONATYPE_USER").orNull
password = providers.environmentVariable("SONATYPE_PASSWORD").orNull
}
name = "SonatypeUpload"
setUrl(layout.buildDirectory.dir("sonatype"))
}
}
}
val releasePublication = publishing.publications.named("release").get() as MavenPublication
val mavenGroupPath = releasePublication.groupId.replace('.', '/')
val mavenArtifactId = releasePublication.artifactId
val mavenVersion = releasePublication.version
tasks.register<Zip>("zipReleasePublication") {
dependsOn(tasks.named("publishReleasePublicationToSonatypeUploadRepository"))
group = "distribution"
description = "Zips the release publication in Maven repository layout."
val sourceDir = layout.buildDirectory.dir("sonatype/${mavenGroupPath}/${mavenArtifactId}/${mavenVersion}")
from(sourceDir)
archiveFileName.set("${mavenArtifactId}-${mavenVersion}-maven.zip")
destinationDirectory.set(layout.buildDirectory.dir("distributions"))
into("${mavenGroupPath}/${mavenArtifactId}/${mavenVersion}")
}
signing {
useGpgCmd()
sign(publishing.publications)
+1 -1
View File
@@ -1,5 +1,5 @@
<!--
~ Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
~ Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
~ SPDX-License-Identifier: Apache-2.0
-->
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -52,6 +52,28 @@ public interface Backend {
*/
String getVersion() throws Exception;
/**
* Determines whether the service is running in always-on VPN mode.
* In this mode the system ensures that the service is always running by restarting it when necessary,
* e.g. after reboot.
*
* @return A boolean indicating whether the service is running in always-on VPN mode.
* @throws Exception Exception raised while retrieving the always-on status.
*/
boolean isAlwaysOn() throws Exception;
/**
* Determines whether the service is running in always-on VPN lockdown mode.
* In this mode the system ensures that the service is always running and that the apps
* aren't allowed to bypass the VPN.
*
* @return A boolean indicating whether the service is running in always-on VPN lockdown mode.
* @throws Exception Exception raised while retrieving the lockdown status.
*/
boolean isLockdownEnabled() throws Exception;
/**
* Set the state of a tunnel, updating it's configuration. If the tunnel is already up, config
* may update the running configuration; config may be null when setting the tunnel down.
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -24,12 +24,10 @@ import com.wireguard.crypto.KeyFormatException;
import com.wireguard.util.NonNullForAll;
import java.net.InetAddress;
import java.time.Instant;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -45,7 +43,7 @@ public final class GoBackend implements Backend {
private static final int DNS_RESOLUTION_RETRIES = 10;
private static final String TAG = "WireGuard/GoBackend";
@Nullable private static AlwaysOnCallback alwaysOnCallback;
private static GhettoCompletableFuture<VpnService> vpnService = new GhettoCompletableFuture<>();
private static CompletableFuture<VpnService> vpnService = new CompletableFuture<>();
private final Context context;
@Nullable private Config currentConfig;
@Nullable private Tunnel currentTunnel;
@@ -188,6 +186,24 @@ public final class GoBackend implements Backend {
return wgVersion();
}
/**
* Determines if the service is running in always-on VPN mode.
* @return {@link boolean} whether the service is running in always-on VPN mode.
*/
@Override
public boolean isAlwaysOn() throws ExecutionException, InterruptedException, TimeoutException {
return vpnService.get(0, TimeUnit.NANOSECONDS).isAlwaysOn();
}
/**
* Determines if the service is running in always-on VPN lockdown mode.
* @return {@link boolean} whether the service is running in always-on VPN lockdown mode.
*/
@Override
public boolean isLockdownEnabled() throws ExecutionException, InterruptedException, TimeoutException {
return vpnService.get(0, TimeUnit.NANOSECONDS).isLockdownEnabled();
}
/**
* Change the state of a given {@link Tunnel}, optionally applying a given {@link Config}.
*
@@ -359,35 +375,6 @@ public final class GoBackend implements Backend {
void alwaysOnTriggered();
}
// TODO: When we finally drop API 21 and move to API 24, delete this and replace with the ordinary CompletableFuture.
private static final class GhettoCompletableFuture<V> {
private final LinkedBlockingQueue<V> completion = new LinkedBlockingQueue<>(1);
private final FutureTask<V> result = new FutureTask<>(completion::peek);
public boolean complete(final V value) {
final boolean offered = completion.offer(value);
if (offered)
result.run();
return offered;
}
public V get() throws ExecutionException, InterruptedException {
return result.get();
}
public V get(final long timeout, final TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException {
return result.get(timeout, unit);
}
public boolean isDone() {
return !completion.isEmpty();
}
public GhettoCompletableFuture<V> newIncompleteFuture() {
return new GhettoCompletableFuture<>();
}
}
/**
* {@link android.net.VpnService} implementation for {@link GoBackend}
*/
@@ -417,7 +404,10 @@ public final class GoBackend implements Backend {
tunnel.onStateChange(State.DOWN);
}
}
vpnService = vpnService.newIncompleteFuture();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
vpnService = vpnService.newIncompleteFuture();
else
vpnService = new CompletableFuture<>();
super.onDestroy();
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -109,6 +109,16 @@ public final class WgQuickBackend implements Backend {
return output.get(0);
}
@Override
public boolean isAlwaysOn() {
return false;
}
@Override
public boolean isLockdownEnabled() {
return false;
}
public void setMultipleTunnels(final boolean on) {
multipleTunnels = on;
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,6 @@
/*
* Copyright © 2016 Southern Storm Software, Pty Ltd.
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
# Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
cmake_minimum_required(VERSION 3.4.1)
project("WireGuard")
+1 -1
View File
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
# Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
BUILDDIR ?= $(CURDIR)/build
DESTDIR ?= $(CURDIR)/out
+1 -1
View File
@@ -4,7 +4,7 @@ go 1.23.1
require (
golang.org/x/sys v0.33.0
golang.zx2c4.com/wireguard v0.0.0-20250515145403-1571e0fbae8e
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb
)
require (
+2 -4
View File
@@ -10,9 +10,7 @@ golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20250515144814-842888ac5c93 h1:7ZEIuxqu71NkNE9klltGsEqv3tiXkUHlZ6aapRGhwwg=
golang.zx2c4.com/wireguard v0.0.0-20250515144814-842888ac5c93/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
golang.zx2c4.com/wireguard v0.0.0-20250515145403-1571e0fbae8e h1:ZB5hAWug6qfyDjed7y2uJB6f1ufSJfJok753/GQ1kCA=
golang.zx2c4.com/wireguard v0.0.0-20250515145403-1571e0fbae8e/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A=
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI=
gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g=
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD
*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
*
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD
*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
*
*/
+1 -1
View File
@@ -21,7 +21,7 @@ android {
namespace = pkg
defaultConfig {
applicationId = pkg
minSdk = 21
minSdk = 24
targetSdk = 36
versionCode = providers.gradleProperty("wireguardVersionCode").get().toInt()
versionName = providers.gradleProperty("wireguardVersionName").get()
+4 -1
View File
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
+4 -1
View File
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android
@@ -32,7 +32,6 @@ import kotlinx.coroutines.launch
* system framework as necessary to update the appearance of the tile in the system UI, and to
* forward click events to the application.
*/
@RequiresApi(Build.VERSION_CODES.N)
class QuickTileService : TileService() {
private val onStateChangedCallback = OnStateChangedCallback()
private val onTunnelChangedCallback = OnTunnelChangedCallback()
@@ -52,33 +51,50 @@ class QuickTileService : TileService() {
}
override fun onClick() {
when (val tunnel = tunnel) {
null -> {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startActivityAndCollapse(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE))
} else {
@Suppress("DEPRECATION")
startActivityAndCollapse(intent)
}
applicationScope.launch {
if (tunnel == null) {
Application.getTunnelManager().getTunnels()
updateTile()
}
else -> {
unlockAndRun {
applicationScope.launch {
try {
tunnel.setStateAsync(Tunnel.State.TOGGLE)
updateTile()
} catch (_: Throwable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && !Settings.canDrawOverlays(this@QuickTileService)) {
val permissionIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName"))
permissionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivityAndCollapse(PendingIntent.getActivity(this@QuickTileService, 0, permissionIntent, PendingIntent.FLAG_IMMUTABLE))
return@launch
when (val tunnel = tunnel) {
null -> {
Log.d(TAG, "No tunnel set, so launching main activity")
val intent = Intent(this@QuickTileService, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startActivityAndCollapse(PendingIntent.getActivity(this@QuickTileService, 0, intent, PendingIntent.FLAG_IMMUTABLE))
} else {
@Suppress("DEPRECATION")
startActivityAndCollapse(intent)
}
}
else -> {
unlockAndRun {
applicationScope.launch {
try {
tunnel.setStateAsync(Tunnel.State.TOGGLE)
updateTile()
} catch (e: Throwable) {
Log.d(TAG, "Failed to set state, so falling back", e)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && !Settings.canDrawOverlays(this@QuickTileService)) {
Log.d(TAG, "Need overlay permissions")
val permissionIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName"))
permissionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivityAndCollapse(
PendingIntent.getActivity(
this@QuickTileService,
0,
permissionIntent,
PendingIntent.FLAG_IMMUTABLE
)
)
return@launch
}
val toggleIntent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
toggleIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(toggleIntent)
}
val toggleIntent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
toggleIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(toggleIntent)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -183,7 +183,7 @@ class LogViewerActivity : AppCompatActivity() {
return
Snackbar.make(
findViewById(android.R.id.content),
if (exception == null) getString(R.string.log_export_success, outputFile?.fileName)
if (exception == null) getString(R.string.log_export_success, outputFile.fileName)
else getString(R.string.log_export_error, ErrorMessages[exception]),
if (exception == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG
)
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
@@ -80,7 +80,7 @@ class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener
R.id.menu_action_edit -> {
supportFragmentManager.commit {
replace(R.id.detail_container, TunnelEditorFragment())
replace(if (isTwoPaneLayout) R.id.detail_container else R.id.list_detail_container, TunnelEditorFragment())
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
addToBackStack(null)
}
@@ -119,7 +119,7 @@ class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener
} else if (backStackEntries == 0) {
// Create and show a new detail fragment.
fragmentManager.commit {
add(R.id.detail_container, TunnelDetailFragment())
add(if (isTwoPaneLayout) R.id.detail_container else R.id.list_detail_container, TunnelDetailFragment())
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
addToBackStack(null)
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
@@ -72,10 +72,6 @@ class SettingsActivity : AppCompatActivity() {
darkTheme?.parent?.removePreference(darkTheme)
--preferenceScreen.initialExpandedChildrenCount
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
val remoteApps = preferenceManager.findPreference<Preference>("allow_remote_control_intents")
remoteApps?.parent?.removePreference(remoteApps)
}
if (AdminKnobs.disableConfigExport) {
val zipExporter = preferenceManager.findPreference<Preference>("zip_exporter")
zipExporter?.parent?.removePreference(zipExporter)
@@ -1,15 +1,11 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import androidx.fragment.app.commit
import com.wireguard.android.fragment.TunnelEditorFragment
import com.wireguard.android.R
import com.wireguard.android.model.ObservableTunnel
/**
@@ -18,20 +14,11 @@ import com.wireguard.android.model.ObservableTunnel
class TunnelCreatorActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (supportFragmentManager.findFragmentById(android.R.id.content) == null) {
supportFragmentManager.commit {
add(android.R.id.content, TunnelEditorFragment())
}
}
setContentView(R.layout.tunnel_creator_activity)
}
override fun onSelectedTunnelChanged(oldTunnel: ObservableTunnel?, newTunnel: ObservableTunnel?): Boolean {
finish()
return true
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
(findViewById<View?>(android.R.id.content) as? ViewGroup)?.children?.firstOrNull()?.fitsSystemWindows = true
}
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
@@ -22,7 +22,6 @@ import com.wireguard.android.backend.Tunnel
import com.wireguard.android.util.ErrorMessages
import kotlinx.coroutines.launch
@RequiresApi(Build.VERSION_CODES.N)
class TunnelToggleActivity : AppCompatActivity() {
private val permissionActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { toggleTunnelWithPermissionsResult() }
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -214,7 +214,10 @@ class TvMainActivity : AppCompatActivity() {
MaterialAlertDialogBuilder(binding.root.context).setMessage(R.string.tv_no_file_picker).setCancelable(false)
.setPositiveButton(android.R.string.ok) { _, _ ->
try {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://webstoreredirect")))
startActivity(Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://play.google.com/store/apps/details?id=com.cxinventor.file.explorer")
setPackage("com.android.vending")
})
} catch (_: Throwable) {
}
}.show()
@@ -263,31 +266,14 @@ class TvMainActivity : AppCompatActivity() {
private suspend fun makeStorageRoots(): Collection<KeyedFile> = withContext(Dispatchers.IO) {
cachedRoots?.let { return@withContext it }
val list = HashSet<KeyedFile>()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val storageManager: StorageManager = getSystemService() ?: return@withContext list
list.addAll(storageManager.storageVolumes.mapNotNull { volume ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
volume.directory?.let { KeyedFile(it, volume.getDescription(this@TvMainActivity)) }
} else {
KeyedFile((StorageVolume::class.java.getMethod("getPathFile").invoke(volume) as File), volume.getDescription(this@TvMainActivity))
}
})
} else {
@Suppress("DEPRECATION")
list.add(KeyedFile(Environment.getExternalStorageDirectory()))
try {
File("/storage").listFiles()?.forEach {
if (!it.isDirectory) return@forEach
try {
if (Environment.isExternalStorageRemovable(it)) {
list.add(KeyedFile(it))
}
} catch (_: Throwable) {
}
}
} catch (_: Throwable) {
val storageManager: StorageManager = getSystemService() ?: return@withContext list
list.addAll(storageManager.storageVolumes.mapNotNull { volume ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
volume.directory?.let { KeyedFile(it, volume.getDescription(this@TvMainActivity)) }
} else {
KeyedFile((StorageVolume::class.java.getMethod("getPathFile").invoke(volume) as File), volume.getDescription(this@TvMainActivity))
}
}
})
cachedRoots = list
list
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.configStore
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.configStore
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.databinding
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.fragment
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.model
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.model
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.model
@@ -221,10 +221,9 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
manager.refreshTunnelStates()
return@launch
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || !UserKnobs.allowRemoteControlIntents.first())
if (!UserKnobs.allowRemoteControlIntents.first())
return@launch
val state: Tunnel.State
state = when (action) {
val state = when (action) {
"com.wireguard.android.action.SET_TUNNEL_UP" -> Tunnel.State.UP
"com.wireguard.android.action.SET_TUNNEL_DOWN" -> Tunnel.State.DOWN
else -> return@launch
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -15,6 +15,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.wireguard.android.R
import com.wireguard.android.updater.Updater
import com.wireguard.android.util.ErrorMessages
import androidx.core.net.toUri
class DonatePreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) {
override fun getSummary() = context.getString(R.string.donate_summary)
@@ -32,7 +33,7 @@ class DonatePreference(context: Context, attrs: AttributeSet?) : Preference(cont
}
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.wireguard.com/donations/")
intent.data = "https://www.wireguard.com/donations/".toUri()
try {
context.startActivity(intent)
} catch (e: Throwable) {
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.preference
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.preference
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.preference
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.preference
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* Copyright 2017 Google Inc.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.updater
@@ -264,7 +264,7 @@ object Updater {
throw IOException("Update could not be fetched: ${connection.responseCode}")
var downloadedByteLen: ULong = 0UL
val totalByteLen = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) connection.contentLengthLong else connection.contentLength).toLong().toULong()
val totalByteLen = connection.contentLengthLong.toULong()
val fileBytes = ByteArray(1024 * 32 /* 32 KiB */)
val digest = MessageDigest.getInstance("SHA-256")
emitProgress(Progress.Downloading(downloadedByteLen, totalByteLen), true)
@@ -376,6 +376,15 @@ object Updater {
if (installerIsGooglePlay(context))
return
if (BuildConfig.BUILD_TYPE == "googleplay") {
if (installer(context).isNotEmpty()) {
applicationScope.launch {
emitProgress(Progress.Corrupt(null))
}
}
return
}
if (if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
@Suppress("DEPRECATION")
context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_PERMISSIONS)
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.util
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.util
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.util
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -29,7 +29,6 @@ class QrCodeFromFileScanner(
private val contentResolver: ContentResolver,
private val reader: Reader,
) {
private fun scanBitmapForResult(source: Bitmap): Result {
val width = source.width
val height = source.height
@@ -40,55 +39,28 @@ class QrCodeFromFileScanner(
return reader.decode(bBitmap, mapOf(DecodeHintType.TRY_HARDER to true))
}
private fun downscaleBitmap(source: Bitmap, scaledSize: Int): Bitmap {
val originalWidth = source.width
val originalHeight = source.height
var newWidth = -1
var newHeight = -1
val multFactor: Float
when {
originalHeight > originalWidth -> {
newHeight = scaledSize
multFactor = originalWidth.toFloat() / originalHeight.toFloat()
newWidth = (newHeight * multFactor).toInt()
}
originalWidth > originalHeight -> {
newWidth = scaledSize
multFactor = originalHeight.toFloat() / originalWidth.toFloat()
newHeight = (newWidth * multFactor).toInt()
}
originalHeight == originalWidth -> {
newHeight = scaledSize
newWidth = scaledSize
}
}
return Bitmap.createScaledBitmap(source, newWidth, newHeight, false)
}
private fun doScan(data: Uri): Result {
Log.d(TAG, "Starting to scan an image: $data")
contentResolver.openInputStream(data).use { inputStream ->
val originalBitmap = BitmapFactory.decodeStream(inputStream)
?: throw IllegalArgumentException("Can't decode stream to Bitmap")
return try {
scanBitmapForResult(originalBitmap).also {
Log.d(TAG, "Found result in original image")
var bitmap: Bitmap? = null
var firstException: Throwable? = null
for (i in arrayOf(1, 2, 4, 8, 16, 32, 64, 128)) {
try {
val options = BitmapFactory.Options()
options.inSampleSize = i
bitmap = BitmapFactory.decodeStream(inputStream, null, options)
?: throw IllegalArgumentException("Can't decode stream for bitmap")
return scanBitmapForResult(bitmap)
} catch (e: Throwable) {
bitmap?.recycle()
System.gc()
Log.e(TAG, "Original image scan at scale factor $i finished with error: $e")
if (firstException == null)
firstException = e
}
} catch (e: Exception) {
Log.e(TAG, "Original image scan finished with error: $e, will try downscaled image")
val scaleBitmap = downscaleBitmap(originalBitmap, 500)
scanBitmapForResult(originalBitmap).also { scaleBitmap.recycle() }
} finally {
originalBitmap.recycle()
}
throw Exception(firstException)
}
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -31,9 +31,6 @@ object QuantityFormatter {
fun formatEpochAgo(epochMillis: Long): String {
var span = (System.currentTimeMillis() - epochMillis) / 1000
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
return Application.get().applicationContext.getString(R.string.latest_handshake_ago, span.seconds.toString())
if (span <= 0L)
return RelativeDateTimeFormatter.getInstance().format(RelativeDateTimeFormatter.Direction.PLAIN, RelativeDateTimeFormatter.AbsoluteUnit.NOW)
val measureFormat = MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE)
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.viewmodel
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.viewmodel
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.viewmodel
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget
@@ -1,6 +1,6 @@
/*
* Copyright © 2018 The Android Open Source Project
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget
@@ -15,7 +15,6 @@ import androidx.annotation.ColorInt
import androidx.annotation.IntRange
import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.N)
class SlashDrawable(private val mDrawable: Drawable) : Drawable() {
private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val mPath = Path()
@@ -1,6 +1,6 @@
/*
* Copyright © 2013 The Android Open Source Project
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget
@@ -1,5 +1,5 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* Copyright © 2017-2025 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

Some files were not shown because too many files have changed in this diff Show More