fix: reset stuck start lock on system Always-on VPN restart (#5958)
* fix: reset stuck start lock on system Always-on VPN restart When Android restarts CoreVpnService for Always-on VPN (via VpnService.SERVICE_INTERFACE or null intent), a stuck isStartingLock from a killed process prevents tryLockStart() from succeeding, causing an immediate return without setupVpnService(). Fix: Reset stuck start lock via unlockStart() on system-initiated VPN start/restart, allowing setupVpnService() to establish the TUN interface. If setup fails during system start, return START_STICKY to keep the service alive for OS reconnection. Also accept LOCKED_BOOT_COMPLETED and MY_PACKAGE_REPLACED in BootReceiver. * Update BootReceiver.kt * Update CoreVpnService.kt --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
1 parent
842567fb89
commit
9896dd2974
3 files changed
+32
-7
No files matched your search
@@ -282,6 +282,8 @@
|
||||
android:label="BootReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.v2ray.ang.receiver
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.UserManager
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.core.CoreServiceManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
@@ -12,18 +13,34 @@ import com.v2ray.ang.util.LogUtil
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
/**
|
||||
* This method is called when the BroadcastReceiver is receiving an Intent broadcast.
|
||||
* It checks if the context is not null and the action is ACTION_BOOT_COMPLETED.
|
||||
* It handles BOOT_COMPLETED, LOCKED_BOOT_COMPLETED, and MY_PACKAGE_REPLACED.
|
||||
* If the conditions are met, it starts the V2Ray service.
|
||||
*
|
||||
* @param context The Context in which the receiver is running.
|
||||
* @param intent The Intent being received.
|
||||
*/
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
LogUtil.i(AppConfig.TAG, "BootReceiver received: ${intent?.action}")
|
||||
val action = intent?.action ?: return
|
||||
if (context == null) return
|
||||
|
||||
if (context == null || intent?.action != Intent.ACTION_BOOT_COMPLETED) {
|
||||
LogUtil.w(AppConfig.TAG, "BootReceiver: Invalid context or action")
|
||||
return
|
||||
LogUtil.i(AppConfig.TAG, "BootReceiver received: $action")
|
||||
|
||||
when (action) {
|
||||
Intent.ACTION_BOOT_COMPLETED,
|
||||
Intent.ACTION_MY_PACKAGE_REPLACED -> {
|
||||
// Continue
|
||||
}
|
||||
Intent.ACTION_LOCKED_BOOT_COMPLETED -> {
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as? UserManager
|
||||
if (userManager != null && !userManager.isUserUnlocked) {
|
||||
LogUtil.w(AppConfig.TAG, "BootReceiver: User is locked, skipping auto start")
|
||||
return
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
LogUtil.w(AppConfig.TAG, "BootReceiver: Unhandled action: $action")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!MmkvManager.decodeStartOnBoot()) {
|
||||
|
||||
@@ -116,20 +116,26 @@ class CoreVpnService : VpnService(), ServiceControl {
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
// Always-on VPN restarts from OS deliver intent.action == SERVICE_INTERFACE or null intent.
|
||||
// Reset any stuck start lock left by a killed process to allow setupVpnService() to run.
|
||||
val isSystemVpnStart = intent == null || intent.action == SERVICE_INTERFACE
|
||||
if (isSystemVpnStart) {
|
||||
unlockStart()
|
||||
}
|
||||
if (!tryLockStart()) {
|
||||
LogUtil.w(AppConfig.TAG, "StartCore-VPN: Start already in progress")
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
LogUtil.i(AppConfig.TAG, "StartCore-VPN: Service command received")
|
||||
LogUtil.i(AppConfig.TAG, "StartCore-VPN: Service command received, systemVpnStart=$isSystemVpnStart")
|
||||
NotificationManager.showNotification(null)
|
||||
if (!setupVpnService()) {
|
||||
unlockStart()
|
||||
// Stop service if setup fails to avoid infinite restart loops (START_STICKY)
|
||||
stopSelf()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
startService()
|
||||
return START_STICKY
|
||||
//return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun getService(): Service {
|
||||
|
||||
Reference in new issue
Block a user