288 lines
9.0 KiB
Kotlin
288 lines
9.0 KiB
Kotlin
package com.hikoncont.service
|
||
|
||
import android.app.*
|
||
import android.content.Context
|
||
import android.content.Intent
|
||
import android.os.IBinder
|
||
import android.os.PowerManager
|
||
import android.util.Log
|
||
import androidx.core.app.NotificationCompat
|
||
import kotlinx.coroutines.*
|
||
import java.io.File
|
||
|
||
/**
|
||
* 进程监控服务
|
||
* 监控主进程状态,在进程被杀死时立即启动恢复机制
|
||
*/
|
||
class ProcessMonitorService : Service() {
|
||
|
||
companion object {
|
||
private const val TAG = "ProcessMonitorService"
|
||
private const val CHECK_INTERVAL = 1000L // ✅ 激进:1秒检查一次进程状态
|
||
private const val NOTIFICATION_ID = 9999
|
||
private const val CHANNEL_ID = "process_monitor_channel"
|
||
|
||
// 进程状态文件路径
|
||
private const val PROCESS_STATUS_FILE = "process_status.txt"
|
||
}
|
||
|
||
private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||
private var monitorJob: Job? = null
|
||
private var wakeLock: PowerManager.WakeLock? = null
|
||
private var notificationManager: NotificationManager? = null
|
||
private var isMonitoring = false
|
||
|
||
override fun onCreate() {
|
||
super.onCreate()
|
||
Log.i(TAG, "🔍 进程监控服务创建")
|
||
|
||
// 初始化通知管理器
|
||
initNotificationManager()
|
||
|
||
// 获取WakeLock保活
|
||
acquireWakeLock()
|
||
|
||
// 启动前台服务
|
||
startForegroundService()
|
||
|
||
// 开始监控
|
||
startMonitoring()
|
||
}
|
||
|
||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||
Log.i(TAG, "🔍 进程监控服务启动命令")
|
||
return START_STICKY
|
||
}
|
||
|
||
override fun onBind(intent: Intent?): IBinder? {
|
||
return null
|
||
}
|
||
|
||
override fun onDestroy() {
|
||
Log.i(TAG, "🛑 进程监控服务销毁")
|
||
|
||
// 释放WakeLock
|
||
releaseWakeLock()
|
||
|
||
// 停止监控
|
||
stopMonitoring()
|
||
|
||
// 启动激进恢复机制
|
||
scheduleAggressiveRecovery()
|
||
|
||
serviceScope.cancel()
|
||
super.onDestroy()
|
||
}
|
||
|
||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||
Log.w(TAG, "🧹 检测到任务被移除(onTaskRemoved),启动激进恢复")
|
||
scheduleAggressiveRecovery()
|
||
super.onTaskRemoved(rootIntent)
|
||
}
|
||
|
||
/**
|
||
* 初始化通知管理器
|
||
*/
|
||
private fun initNotificationManager() {
|
||
try {
|
||
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||
|
||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||
val channel = NotificationChannel(
|
||
CHANNEL_ID,
|
||
"进程监控服务",
|
||
NotificationManager.IMPORTANCE_LOW
|
||
).apply {
|
||
description = "监控主进程状态"
|
||
setShowBadge(false)
|
||
}
|
||
notificationManager?.createNotificationChannel(channel)
|
||
}
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 初始化通知管理器失败", e)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 启动前台服务
|
||
*/
|
||
private fun startForegroundService() {
|
||
try {
|
||
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
||
.setContentTitle("进程监控服务")
|
||
.setContentText("正在监控主进程状态")
|
||
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
||
.setOngoing(true)
|
||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||
.build()
|
||
|
||
startForeground(NOTIFICATION_ID, notification)
|
||
Log.i(TAG, "✅ 前台服务已启动")
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 启动前台服务失败", e)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取WakeLock保活
|
||
*/
|
||
private fun acquireWakeLock() {
|
||
try {
|
||
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
|
||
wakeLock = powerManager.newWakeLock(
|
||
PowerManager.PARTIAL_WAKE_LOCK,
|
||
"RemoteControl::ProcessMonitorService"
|
||
)
|
||
wakeLock?.acquire(24 * 60 * 60 * 1000L) // 24小时
|
||
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已获取")
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 获取ProcessMonitorService WakeLock失败", e)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 释放WakeLock
|
||
*/
|
||
private fun releaseWakeLock() {
|
||
try {
|
||
wakeLock?.let {
|
||
if (it.isHeld) {
|
||
it.release()
|
||
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已释放")
|
||
}
|
||
}
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 释放ProcessMonitorService WakeLock失败", e)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 开始监控
|
||
*/
|
||
private fun startMonitoring() {
|
||
if (isMonitoring) {
|
||
Log.w(TAG, "⚠️ 进程监控已在运行")
|
||
return
|
||
}
|
||
|
||
isMonitoring = true
|
||
Log.i(TAG, "🔍 开始进程状态监控")
|
||
|
||
monitorJob = serviceScope.launch {
|
||
while (isActive && isMonitoring) {
|
||
try {
|
||
// 更新进程状态文件
|
||
updateProcessStatus()
|
||
|
||
// 检查主进程是否存活
|
||
if (!isMainProcessAlive()) {
|
||
Log.w(TAG, "⚠️ 检测到主进程死亡,启动恢复机制")
|
||
scheduleAggressiveRecovery()
|
||
}
|
||
|
||
delay(CHECK_INTERVAL)
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 进程监控异常", e)
|
||
delay(CHECK_INTERVAL)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 停止监控
|
||
*/
|
||
private fun stopMonitoring() {
|
||
isMonitoring = false
|
||
monitorJob?.cancel()
|
||
Log.i(TAG, "🛑 进程监控已停止")
|
||
}
|
||
|
||
/**
|
||
* 更新进程状态文件
|
||
*/
|
||
private fun updateProcessStatus() {
|
||
try {
|
||
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
||
val currentTime = System.currentTimeMillis()
|
||
val pid = android.os.Process.myPid()
|
||
|
||
statusFile.writeText("$pid:$currentTime")
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 更新进程状态文件失败", e)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查主进程是否存活
|
||
*/
|
||
private fun isMainProcessAlive(): Boolean {
|
||
return try {
|
||
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
||
if (!statusFile.exists()) {
|
||
return false
|
||
}
|
||
|
||
val content = statusFile.readText()
|
||
val parts = content.split(":")
|
||
if (parts.size != 2) {
|
||
return false
|
||
}
|
||
|
||
val timestamp = parts[1].toLongOrNull() ?: return false
|
||
val currentTime = System.currentTimeMillis()
|
||
|
||
// 如果状态文件超过5秒没有更新,认为进程死亡
|
||
(currentTime - timestamp) < 5000
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 检查主进程状态失败", e)
|
||
false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 启动激进恢复机制
|
||
*/
|
||
private fun scheduleAggressiveRecovery() {
|
||
try {
|
||
Log.i(TAG, "🚀 启动激进恢复机制")
|
||
|
||
// 立即启动前台服务
|
||
val rcfsIntent = Intent(this, RemoteControlForegroundService::class.java).apply {
|
||
action = "RESTART_SERVICE"
|
||
}
|
||
startForegroundService(rcfsIntent)
|
||
|
||
// 立即启动保活服务
|
||
val keepAliveIntent = Intent(this, KeepAliveService::class.java)
|
||
startService(keepAliveIntent)
|
||
|
||
// 使用AlarmManager安排延迟恢复
|
||
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||
|
||
val rcfsPI = PendingIntent.getForegroundService(
|
||
this,
|
||
(System.currentTimeMillis() % 10000).toInt(),
|
||
rcfsIntent,
|
||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||
)
|
||
|
||
val keepAlivePI = PendingIntent.getService(
|
||
this,
|
||
(System.currentTimeMillis() % 10000).toInt() + 1,
|
||
keepAliveIntent,
|
||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||
)
|
||
|
||
val triggerAt = System.currentTimeMillis() + 50 // 50ms延迟
|
||
|
||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, rcfsPI)
|
||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt + 50, keepAlivePI)
|
||
|
||
Log.i(TAG, "✅ 激进恢复机制已启动")
|
||
} catch (e: Exception) {
|
||
Log.e(TAG, "❌ 启动激进恢复机制失败", e)
|
||
}
|
||
}
|
||
}
|