55
66package com .wireguard .android .backend ;
77
8+ import android .app .ForegroundServiceStartNotAllowedException ;
9+ import android .app .Notification ;
810import android .content .Context ;
911import android .content .Intent ;
12+ import android .content .pm .ServiceInfo ;
1013import android .os .Build ;
1114import android .os .ParcelFileDescriptor ;
1215import android .system .OsConstants ;
2427import com .wireguard .util .NonNullForAll ;
2528
2629import java .net .InetAddress ;
27- import java .time .Instant ;
2830import java .util .Collections ;
2931import java .util .Set ;
3032import java .util .concurrent .ExecutionException ;
3537
3638import androidx .annotation .Nullable ;
3739import androidx .collection .ArraySet ;
40+ import androidx .core .app .NotificationCompat ;
41+ import androidx .core .app .ServiceCompat ;
3842
3943/**
4044 * Implementation of {@link Backend} that uses the wireguard-go userspace implementation to provide
@@ -392,6 +396,9 @@ public GhettoCompletableFuture<V> newIncompleteFuture() {
392396 * {@link android.net.VpnService} implementation for {@link GoBackend}
393397 */
394398 public static class VpnService extends android .net .VpnService {
399+
400+ private static final int NOTIFICATION_ID = 999 ;
401+ private static final String CHANNEL_ID = "VPN_CHANNEL" ;
395402 @ Nullable private GoBackend owner ;
396403
397404 public Builder getBuilder () {
@@ -423,6 +430,7 @@ public void onDestroy() {
423430
424431 @ Override
425432 public int onStartCommand (@ Nullable final Intent intent , final int flags , final int startId ) {
433+ startForeground ();
426434 vpnService .complete (this );
427435 if (intent == null || intent .getComponent () == null || !intent .getComponent ().getPackageName ().equals (getPackageName ())) {
428436 Log .d (TAG , "Service started by Always-on VPN feature" );
@@ -435,5 +443,20 @@ public int onStartCommand(@Nullable final Intent intent, final int flags, final
435443 public void setOwner (final GoBackend owner ) {
436444 this .owner = owner ;
437445 }
446+
447+ private void startForeground () {
448+ try {
449+ final Notification notification = new NotificationCompat
450+ .Builder (this , CHANNEL_ID )
451+ .build ();
452+ ServiceCompat .startForeground (this , NOTIFICATION_ID , notification , ServiceInfo .FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED );
453+ } catch (final Exception ex ) {
454+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S &&
455+ ex instanceof ForegroundServiceStartNotAllowedException
456+ ) {
457+ Log .d (TAG , "App not in a valid state to start foreground service" );
458+ }
459+ }
460+ }
438461 }
439462}
0 commit comments