@ -10,27 +10,28 @@ import android.os.Build
import android.system.OsConstants
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import libtailscale.Libtailscale
import java.util.UUID
import libtailscale.Libtailscale
open class IPNService : VpnService ( ) , libtailscale . IPNService {
private val randomID : String = UUID . randomUUID ( ) . toString ( )
override fun id ( ) : String {
return randomID
}
override fun onStartCommand ( intent : Intent , flags : Int , startId : Int ) : Int {
if ( intent != null && ACTION _STOP _VPN == intent . getAction( ) ) {
( getApplicationContext ( ) as App ) . autoConnect = false
override fun onStartCommand ( intent : Intent ? , flags : Int , startId : Int ) : Int {
if ( intent != null && ACTION _STOP _VPN == intent . action ) {
( applicationContext as App ) . autoConnect = false
close ( )
return START _NOT _STICKY
}
val app = getApplicationContext ( ) as App
if ( intent != null && " android.net.VpnService " == intent . getAction( ) ) {
val app = applicationContext as App
if ( intent != null && " android.net.VpnService " == intent . action ) {
// Start VPN and connect to it due to Always-on VPN
val i = Intent ( IPNReceiver . INTENT _CONNECT _VPN )
i . setPackage ( getPackageName( ) )
i . setClass ( getApplicationContext( ) , IPNReceiver :: class . java )
i . setPackage ( packageName )
i . setClass ( applicationContext , IPNReceiver :: class . java )
sendBroadcast ( i )
Libtailscale . requestVPN ( this )
app . setWantRunning ( true )
@ -38,12 +39,11 @@ open class IPNService : VpnService(), libtailscale.IPNService {
}
Libtailscale . requestVPN ( this )
if ( app . vpnReady && app . autoConnect ) {
app . setWantRunning ( true ) ;
app . setWantRunning ( true )
}
return START _STICKY
}
private fun close ( ) {
stopForeground ( true )
Libtailscale . serviceDisconnect ( this )
@ -60,24 +60,29 @@ open class IPNService : VpnService(), libtailscale.IPNService {
}
private fun configIntent ( ) : PendingIntent {
return PendingIntent . getActivity ( this , 0 , Intent ( this , IPNActivity :: class . java ) ,
return PendingIntent . getActivity (
this ,
0 ,
Intent ( this , IPNActivity :: class . java ) ,
PendingIntent . FLAG _UPDATE _CURRENT or PendingIntent . FLAG _IMMUTABLE )
}
private fun disallowApp ( b : Builder , name : String ) {
try {
b . addDisallowedApplication ( name )
} catch ( e : PackageManager . NameNotFoundException ) {
}
} catch ( e : PackageManager . NameNotFoundException ) { }
}
override fun newBuilder ( ) : VPNServiceBuilder {
val b : Builder = Builder ( )
val b : Builder =
Builder ( )
. setConfigureIntent ( configIntent ( ) )
. allowFamily ( OsConstants . AF _INET )
. allowFamily ( OsConstants . AF _INET6 )
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . Q ) b . setMetered ( false ) // Inherit the metered status from the underlying networks.
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . M ) b . setUnderlyingNetworks ( null ) // Use all available networks.
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . Q )
b . setMetered ( false ) // Inherit the metered status from the underlying networks.
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . M )
b . setUnderlyingNetworks ( null ) // Use all available networks.
// RCS/Jibe https://github.com/tailscale/tailscale/issues/2322
disallowApp ( b , " com.google.android.apps.messaging " )
@ -101,7 +106,8 @@ open class IPNService : VpnService(), libtailscale.IPNService {
}
fun notify ( title : String ? , message : String ? ) {
val builder : NotificationCompat . Builder = NotificationCompat . Builder ( this , App . NOTIFY _CHANNEL _ID )
val builder : NotificationCompat . Builder =
NotificationCompat . Builder ( this , App . NOTIFY _CHANNEL _ID )
. setSmallIcon ( R . drawable . ic _notification )
. setContentTitle ( title )
. setContentText ( message )
@ -114,7 +120,8 @@ open class IPNService : VpnService(), libtailscale.IPNService {
}
fun updateStatusNotification ( title : String ? , message : String ? ) {
val builder : NotificationCompat . Builder = NotificationCompat . Builder ( this , App . STATUS _CHANNEL _ID )
val builder : NotificationCompat . Builder =
NotificationCompat . Builder ( this , App . STATUS _CHANNEL _ID )
. setSmallIcon ( R . drawable . ic _notification )
. setContentTitle ( title )
. setContentText ( message )