181 lines
6.3 KiB
Kotlin
181 lines
6.3 KiB
Kotlin
package com.yingmao.clash.levellog
|
|
|
|
import android.app.PendingIntent
|
|
import android.app.Service
|
|
import android.content.ComponentName
|
|
import android.content.Intent
|
|
import android.content.ServiceConnection
|
|
import android.os.Binder
|
|
import android.os.Build
|
|
import android.os.IBinder
|
|
import android.os.IInterface
|
|
import android.util.Log
|
|
import androidx.annotation.RequiresApi
|
|
import androidx.core.app.NotificationChannelCompat
|
|
import androidx.core.app.NotificationCompat
|
|
import androidx.core.app.NotificationManagerCompat
|
|
import com.cncat.vpn.common.compat.getColorCompat
|
|
import com.cncat.vpn.common.compat.pendingIntentFlags
|
|
import com.cncat.vpn.common.compat.startForegroundCompat
|
|
import com.cncat.vpn.common.util.intent
|
|
import com.cncat.vpn.core.model.LogMessage
|
|
import com.cncat.vpn.service.RemoteService
|
|
import com.cncat.vpn.service.remote.ILogObserver
|
|
import com.cncat.vpn.service.remote.IRemoteService
|
|
import com.cncat.vpn.service.remote.unwrap
|
|
import com.tencent.mmkv.MMKV
|
|
import com.yingmao.clash.R
|
|
import com.yingmao.clash.act.SettingActivity
|
|
import com.yingmao.clash.app.MainApplication
|
|
import com.yingmao.clash.conf.BZYConstants
|
|
import com.yingmao.clash.util.Utils
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.NonCancellable
|
|
import kotlinx.coroutines.cancel
|
|
import kotlinx.coroutines.channels.Channel
|
|
import kotlinx.coroutines.isActive
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.IOException
|
|
|
|
class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.Default), IInterface {
|
|
private val connection = object : ServiceConnection {
|
|
override fun onServiceDisconnected(name: ComponentName?) {
|
|
Log.i("LogcatServiceClose","onServiceDisconnected::${name}")
|
|
stopSelf()
|
|
}
|
|
|
|
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
|
Log.i("LogcatServiceConnect","onServiceConnected::${name}")
|
|
startObserver(service ?: return stopSelf())
|
|
}
|
|
}
|
|
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
|
|
running = true
|
|
|
|
createNotificationChannel()
|
|
|
|
showNotification()
|
|
|
|
bindService(RemoteService::class.intent, connection, BIND_AUTO_CREATE)
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
cancel()
|
|
|
|
unbindService(connection)
|
|
|
|
stopForeground(true)
|
|
|
|
running = false
|
|
|
|
super.onDestroy()
|
|
}
|
|
|
|
override fun onBind(intent: Intent?): IBinder {
|
|
return this.asBinder()
|
|
}
|
|
|
|
override fun asBinder(): IBinder {
|
|
return object : Binder() {
|
|
override fun queryLocalInterface(descriptor: String): IInterface {
|
|
return this@LogcatService
|
|
}
|
|
}
|
|
}
|
|
|
|
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
|
private fun startObserver(binder: IBinder) {
|
|
if (!binder.isBinderAlive)
|
|
return stopSelf()
|
|
|
|
launch(Dispatchers.IO) {
|
|
val service = binder.unwrap(IRemoteService::class).clash()
|
|
val channel = Channel<LogMessage>(CACHE_CAPACITY)
|
|
|
|
try {
|
|
MMKV.defaultMMKV().encode(BZYConstants.Companion.BehaviorLogSwitch, true)
|
|
val selectedName =
|
|
MMKV.defaultMMKV().decodeString(BZYConstants.Companion.NODE_SELECTED_NAME_KEY, "")
|
|
val equipmentModel = Utils.getEquipmentModel()
|
|
AppLog.i("LogcatService", "selectedName===>${selectedName}")
|
|
AppLog.i("LogcatService", "用户是否过期===>${checkExpire()}")
|
|
AppLog.i("LogcatService", "机型数据===>${equipmentModel}")
|
|
AppLog.i("LogcatService", "OAID===>${MainApplication.Companion.OAID}")
|
|
val observer = object : ILogObserver {
|
|
override fun newItem(log: LogMessage) {
|
|
channel.trySend(log)
|
|
}
|
|
}
|
|
service.setLogObserver(observer)
|
|
while (isActive) {
|
|
val msg = channel.receive()
|
|
AppLog.i("LogcatServiceMsg", "core msg===>${msg}")
|
|
}
|
|
} catch (e: IOException) {
|
|
Log.e("Write log file: $e", e.toString())
|
|
} finally {
|
|
withContext(NonCancellable) {
|
|
if (binder.isBinderAlive) {
|
|
service.setLogObserver(null)
|
|
}
|
|
stopSelf()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun createNotificationChannel() {
|
|
NotificationManagerCompat.from(this)
|
|
.createNotificationChannel(
|
|
NotificationChannelCompat.Builder(
|
|
CHANNEL_ID,
|
|
NotificationManagerCompat.IMPORTANCE_DEFAULT
|
|
).setName(getString(R.string.clash_logcat)).build()
|
|
)
|
|
}
|
|
|
|
private fun showNotification() {
|
|
val notification = NotificationCompat
|
|
.Builder(this, CHANNEL_ID)
|
|
.setSmallIcon(R.mipmap.oneclickconnection)
|
|
.setColor(getColorCompat(R.color.color_clash))
|
|
.setContentTitle(getString(R.string.clash_logcat))
|
|
.setContentText("采集中")
|
|
.setContentIntent(
|
|
PendingIntent.getActivity(
|
|
this,
|
|
R.id.nf_logcat_status,
|
|
SettingActivity::class.intent
|
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP),
|
|
pendingIntentFlags(PendingIntent.FLAG_UPDATE_CURRENT)
|
|
)
|
|
)
|
|
.build()
|
|
|
|
startForegroundCompat(R.id.nf_logcat_status, notification)
|
|
}
|
|
|
|
companion object {
|
|
private const val CHANNEL_ID = "clash_logcat_channel_id"
|
|
private const val CACHE_CAPACITY = 129
|
|
|
|
var running: Boolean = false
|
|
}
|
|
private fun checkExpire(): Boolean {
|
|
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.Companion.MMKV_KEY_VPN_VALID_PERIOD)
|
|
if (validPeriod > 0) {
|
|
val nowTime = System.currentTimeMillis();
|
|
com.cncat.vpn.common.log.Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
|
|
if (validPeriod >= nowTime) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
} |