Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tunnel/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ android {
dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.collection)
implementation(libs.androidx.core.ktx)
compileOnly(libs.jsr305)
testImplementation(libs.junit)
}
Expand Down
6 changes: 5 additions & 1 deletion tunnel/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED" />

<application>
<service
android:name="com.wireguard.android.backend.GoBackend$VpnService"
android:permission="android.permission.BIND_VPN_SERVICE"
android:exported="false">
android:exported="false"
android:persistent="true"
android:foregroundServiceType="systemExempted">
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@

package com.wireguard.android.backend;

import android.app.ForegroundServiceStartNotAllowedException;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.system.OsConstants;
Expand All @@ -24,7 +29,6 @@
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.ExecutionException;
Expand All @@ -35,6 +39,8 @@

import androidx.annotation.Nullable;
import androidx.collection.ArraySet;
import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;

/**
* Implementation of {@link Backend} that uses the wireguard-go userspace implementation to provide
Expand Down Expand Up @@ -392,6 +398,9 @@ public GhettoCompletableFuture<V> newIncompleteFuture() {
* {@link android.net.VpnService} implementation for {@link GoBackend}
*/
public static class VpnService extends android.net.VpnService {

private static final int NOTIFICATION_ID = 999;
private static final String CHANNEL_ID = "WireGuardChannel";
@Nullable private GoBackend owner;

public Builder getBuilder() {
Expand Down Expand Up @@ -423,6 +432,7 @@ public void onDestroy() {

@Override
public int onStartCommand(@Nullable final Intent intent, final int flags, final int startId) {
startForeground();
vpnService.complete(this);
if (intent == null || intent.getComponent() == null || !intent.getComponent().getPackageName().equals(getPackageName())) {
Log.d(TAG, "Service started by Always-on VPN feature");
Expand All @@ -435,5 +445,42 @@ public int onStartCommand(@Nullable final Intent intent, final int flags, final
public void setOwner(final GoBackend owner) {
this.owner = owner;
}

private void startForeground() {
try {
createNotificationChannel();
final Notification notification = new NotificationCompat
.Builder(this, CHANNEL_ID)
.build();
ServiceCompat.startForeground(this, NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED);
} catch (final Exception ex) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
ex instanceof ForegroundServiceStartNotAllowedException
) {
Log.d(TAG, "App not in a valid state to start foreground service");
}
}
}

private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
final NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) {
final NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"WireGuard VPN Service",
NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("VPN connection status notifications");
channel.setShowBadge(false);
channel.enableLights(false);
channel.enableVibration(false);

notificationManager.createNotificationChannel(channel);
}
}
}
}
}
1 change: 1 addition & 0 deletions wireguard-android
Submodule wireguard-android added at f0b45d