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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't exist in the library because it's meant to be reusable for other apps that aren't the official WireGuard app. We'll have to either expose a separate API to let integrators provide their own notification or just move this fully to the ui module.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's not the best solution but now it's quite tricky to run this VPN service on a new devices without foreground service support because Android system becomes more and more strict and can kill Vpn service.
You can read about it here.
Do we have a plan/workaround how to promote service to foreground?

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this is about?

Submodule wireguard-android added at f0b45d