improve selector

This commit is contained in:
arm64v8a 2023-04-30 09:23:32 +09:00
parent 6559e70b82
commit c3aafbfdc9
7 changed files with 41 additions and 41 deletions

View File

@ -280,10 +280,12 @@ class SagerNet : Application(),
.filterValues { it == tag }.keys.firstOrNull() ?: -1 .filterValues { it == tag }.keys.firstOrNull() ?: -1
val ent = SagerDatabase.proxyDao.getById(id) ?: return@runOnDefaultDispatcher val ent = SagerDatabase.proxyDao.getById(id) ?: return@runOnDefaultDispatcher
// traffic & title // traffic & title
data.proxy!!.looper?.selectMain(id) data.proxy?.apply {
val title = ServiceNotification.genTitle(ent) looper?.selectMain(id)
data.notification?.postNotificationTitle(title) displayProfileName = ServiceNotification.genTitle(ent)
// post MainActivity animation data.notification?.postNotificationTitle(displayProfileName)
}
// post binder
data.binder.broadcast { b -> data.binder.broadcast { b ->
b.cbSelectorUpdate(id) b.cbSelectorUpdate(id)
} }

View File

@ -88,7 +88,7 @@ class BaseService {
override val coroutineContext = Dispatchers.Main.immediate + Job() override val coroutineContext = Dispatchers.Main.immediate + Job()
override fun getState(): Int = (data?.state ?: State.Idle).ordinal override fun getState(): Int = (data?.state ?: State.Idle).ordinal
override fun getProfileName(): String = data?.proxy?.profile?.displayName() ?: "Idle" override fun getProfileName(): String = data?.proxy?.displayProfileName ?: "Idle"
override fun registerCallback(cb: ISagerNetServiceCallback, id: Int) { override fun registerCallback(cb: ISagerNetServiceCallback, id: Int) {
if (!callbackIdMap.contains(cb)) { if (!callbackIdMap.contains(cb)) {
@ -189,7 +189,6 @@ class BaseService {
tmpBox.buildConfigTmp() tmpBox.buildConfigTmp()
if (tmpBox.lastSelectorGroupId == data.proxy?.lastSelectorGroupId) { if (tmpBox.lastSelectorGroupId == data.proxy?.lastSelectorGroupId) {
return true return true
// TODO if profile changed?
} }
return false return false
} }

View File

@ -1,23 +1,3 @@
/*******************************************************************************
* *
* Copyright (C) 2017 by Max Lv <max.c.lv@gmail.com> *
* Copyright (C) 2017 by Mygod Studio <contact-shadowsocks-android@mygod.be> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
package io.nekohasekai.sagernet.bg package io.nekohasekai.sagernet.bg
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
@ -26,6 +6,7 @@ import androidx.annotation.RequiresApi
import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.SagerNet import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.aidl.ISagerNetService import io.nekohasekai.sagernet.aidl.ISagerNetService
import io.nekohasekai.sagernet.database.SagerDatabase
import android.service.quicksettings.TileService as BaseTileService import android.service.quicksettings.TileService as BaseTileService
@RequiresApi(24) @RequiresApi(24)
@ -39,16 +20,21 @@ class TileService : BaseTileService(), SagerConnection.Callback {
private val connection = SagerConnection(SagerConnection.CONNECTION_ID_TILE) private val connection = SagerConnection(SagerConnection.CONNECTION_ID_TILE)
override fun stateChanged(state: BaseService.State, profileName: String?, msg: String?) = override fun stateChanged(state: BaseService.State, profileName: String?, msg: String?) =
updateTile(state) { profileName } updateTile(state, profileName)
override fun onServiceConnected(service: ISagerNetService) { override fun onServiceConnected(service: ISagerNetService) {
updateTile(BaseService.State.values()[service.state]) { service.profileName } updateTile(BaseService.State.values()[service.state], service.profileName)
if (tapPending) { if (tapPending) {
tapPending = false tapPending = false
onClick() onClick()
} }
} }
override fun cbSelectorUpdate(id: Long) {
val profile = SagerDatabase.proxyDao.getById(id) ?: return
updateTile(BaseService.State.Connected, profile.displayName())
}
override fun onStartListening() { override fun onStartListening() {
super.onStartListening() super.onStartListening()
connection.connect(this, this) connection.connect(this, this)
@ -63,7 +49,7 @@ class TileService : BaseTileService(), SagerConnection.Callback {
if (isLocked) unlockAndRun(this::toggle) else toggle() if (isLocked) unlockAndRun(this::toggle) else toggle()
} }
private fun updateTile(serviceState: BaseService.State, profileName: () -> String?) { private fun updateTile(serviceState: BaseService.State, profileName: String?) {
qsTile?.apply { qsTile?.apply {
label = null label = null
when (serviceState) { when (serviceState) {
@ -75,7 +61,7 @@ class TileService : BaseTileService(), SagerConnection.Callback {
BaseService.State.Connected -> { BaseService.State.Connected -> {
icon = iconConnected icon = iconConnected
label = profileName() label = profileName
state = Tile.STATE_ACTIVE state = Tile.STATE_ACTIVE
} }

View File

@ -95,9 +95,8 @@ class VpnService : BaseVpnService(),
// val tunOptions = JSONObject(tunOptionsJson) // val tunOptions = JSONObject(tunOptionsJson)
// address & route & MTU ...... use NB4A GUI config // address & route & MTU ...... use NB4A GUI config
val profile = data.proxy!!.profile
val builder = Builder().setConfigureIntent(SagerNet.configureIntent(this)) val builder = Builder().setConfigureIntent(SagerNet.configureIntent(this))
.setSession(profile.displayName()) .setSession(getString(R.string.app_name))
.setMtu(DataStore.mtu) .setMtu(DataStore.mtu)
val ipv6Mode = DataStore.ipv6Mode val ipv6Mode = DataStore.ipv6Mode
@ -132,10 +131,10 @@ class VpnService : BaseVpnService(),
// app route // app route
val packageName = packageName val packageName = packageName
var proxyApps = DataStore.proxyApps val proxyApps = DataStore.proxyApps
var bypass = DataStore.bypass var bypass = DataStore.bypass
var workaroundSYSTEM = false /* DataStore.tunImplementation == TunImplementation.SYSTEM */ val workaroundSYSTEM = false /* DataStore.tunImplementation == TunImplementation.SYSTEM */
var needBypassRootUid = workaroundSYSTEM || data.proxy!!.config.trafficMap.values.any { val needBypassRootUid = workaroundSYSTEM || data.proxy!!.config.trafficMap.values.any {
it[0].nekoBean?.needBypassRootUid() == true || it[0].hysteriaBean?.protocol == HysteriaBean.PROTOCOL_FAKETCP it[0].nekoBean?.needBypassRootUid() == true || it[0].hysteriaBean?.protocol == HysteriaBean.PROTOCOL_FAKETCP
} }

View File

@ -67,10 +67,12 @@ abstract class BoxInstance(
initPlugin("trojan-go-plugin") initPlugin("trojan-go-plugin")
pluginConfigs[port] = profile.type to bean.buildTrojanGoConfig(port) pluginConfigs[port] = profile.type to bean.buildTrojanGoConfig(port)
} }
is NaiveBean -> { is NaiveBean -> {
initPlugin("naive-plugin") initPlugin("naive-plugin")
pluginConfigs[port] = profile.type to bean.buildNaiveConfig(port) pluginConfigs[port] = profile.type to bean.buildNaiveConfig(port)
} }
is HysteriaBean -> { is HysteriaBean -> {
initPlugin("hysteria-plugin") initPlugin("hysteria-plugin")
pluginConfigs[port] = profile.type to bean.buildHysteriaConfig(port) { pluginConfigs[port] = profile.type to bean.buildHysteriaConfig(port) {
@ -82,6 +84,7 @@ abstract class BoxInstance(
} }
} }
} }
is TuicBean -> { is TuicBean -> {
initPlugin("tuic-plugin") initPlugin("tuic-plugin")
pluginConfigs[port] = profile.type to bean.buildTuicConfig(port) { pluginConfigs[port] = profile.type to bean.buildTuicConfig(port) {
@ -94,6 +97,7 @@ abstract class BoxInstance(
} }
} }
} }
is NekoBean -> { is NekoBean -> {
// check if plugin binary can be loaded // check if plugin binary can be loaded
initPlugin(bean.plgId) initPlugin(bean.plgId)
@ -127,6 +131,7 @@ abstract class BoxInstance(
externalInstances.containsKey(port) -> { externalInstances.containsKey(port) -> {
externalInstances[port]!!.launch() externalInstances[port]!!.launch()
} }
bean is TrojanGoBean -> { bean is TrojanGoBean -> {
val configFile = File( val configFile = File(
cache, "trojan_go_" + SystemClock.elapsedRealtime() + ".json" cache, "trojan_go_" + SystemClock.elapsedRealtime() + ".json"
@ -141,6 +146,7 @@ abstract class BoxInstance(
processes.start(commands) processes.start(commands)
} }
bean is NaiveBean -> { bean is NaiveBean -> {
val configFile = File( val configFile = File(
cache, "naive_" + SystemClock.elapsedRealtime() + ".json" cache, "naive_" + SystemClock.elapsedRealtime() + ".json"
@ -170,6 +176,7 @@ abstract class BoxInstance(
processes.start(commands, envMap) processes.start(commands, envMap)
} }
bean is HysteriaBean -> { bean is HysteriaBean -> {
val configFile = File( val configFile = File(
cache, "hysteria_" + SystemClock.elapsedRealtime() + ".json" cache, "hysteria_" + SystemClock.elapsedRealtime() + ".json"
@ -195,6 +202,7 @@ abstract class BoxInstance(
processes.start(commands) processes.start(commands)
} }
bean is NekoBean -> { bean is NekoBean -> {
// config built from JS // config built from JS
val nekoRunConfigs = bean.allConfig.optJSONArray("nekoRunConfigs") val nekoRunConfigs = bean.allConfig.optJSONArray("nekoRunConfigs")
@ -232,6 +240,7 @@ abstract class BoxInstance(
processes.start(commands) processes.start(commands)
} }
bean is TuicBean -> { bean is TuicBean -> {
val configFile = File( val configFile = File(
context.noBackupFilesDir, context.noBackupFilesDir,

View File

@ -2,6 +2,7 @@ package io.nekohasekai.sagernet.bg.proto
import io.nekohasekai.sagernet.BuildConfig import io.nekohasekai.sagernet.BuildConfig
import io.nekohasekai.sagernet.bg.BaseService import io.nekohasekai.sagernet.bg.BaseService
import io.nekohasekai.sagernet.bg.ServiceNotification
import io.nekohasekai.sagernet.database.ProxyEntity import io.nekohasekai.sagernet.database.ProxyEntity
import io.nekohasekai.sagernet.ktx.Logs import io.nekohasekai.sagernet.ktx.Logs
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
@ -11,9 +12,11 @@ import moe.matsuri.nb4a.utils.JavaUtil
class ProxyInstance(profile: ProxyEntity, var service: BaseService.Interface? = null) : class ProxyInstance(profile: ProxyEntity, var service: BaseService.Interface? = null) :
BoxInstance(profile) { BoxInstance(profile) {
var lastSelectorGroupId = -1L
var notTmp = true var notTmp = true
var lastSelectorGroupId = -1L
var displayProfileName = ServiceNotification.genTitle(profile)
// for TrafficLooper // for TrafficLooper
var looper: TrafficLooper? = null var looper: TrafficLooper? = null

View File

@ -61,11 +61,13 @@ class TrafficLooper
tag = selectorNowFakeTag tag = selectorNowFakeTag
ignore = true ignore = true
// post traffic when switch // post traffic when switch
data.proxy?.config?.trafficMap?.get(tag)?.firstOrNull()?.let { if (DataStore.profileTrafficStatistics) {
it.rx = rx data.proxy?.config?.trafficMap?.get(tag)?.firstOrNull()?.let {
it.tx = tx it.rx = rx
runOnDefaultDispatcher { it.tx = tx
ProfileManager.updateProfile(it) // update DB runOnDefaultDispatcher {
ProfileManager.updateProfile(it) // update DB
}
} }
} }
} }