Minor fixes

This commit is contained in:
世界 2024-06-26 01:23:25 +08:00
parent fba1072910
commit 8df5f10d61
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
11 changed files with 101 additions and 115 deletions

View file

@ -3,6 +3,4 @@ package io.nekohasekai.sfa.aidl;
interface IServiceCallback {
void onServiceStatusChanged(int status);
void onServiceAlert(int type, String message);
void onServiceWriteLog(String message);
void onServiceResetLogs(in List<String> messages);
}

View file

@ -30,7 +30,6 @@ import io.nekohasekai.sfa.ktx.hasPermission
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@ -74,14 +73,6 @@ class BoxService(
)
)
}
fun reload() {
Application.application.sendBroadcast(
Intent(Action.SERVICE_RELOAD).setPackage(
Application.application.packageName
)
)
}
}
var fileDescriptor: ParcelFileDescriptor? = null
@ -99,9 +90,6 @@ class BoxService(
stopService()
}
Action.SERVICE_RELOAD -> {
serviceReload()
}
PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@ -120,7 +108,7 @@ class BoxService(
}
private var lastProfileName = ""
private suspend fun startService(delayStart: Boolean = false) {
private suspend fun startService() {
try {
withContext(Dispatchers.Main) {
notification.show(lastProfileName, R.string.status_starting)
@ -147,9 +135,6 @@ class BoxService(
lastProfileName = profile.name
withContext(Dispatchers.Main) {
notification.show(lastProfileName, R.string.status_starting)
binder.broadcast {
it.onServiceResetLogs(listOf())
}
}
DefaultNetworkMonitor.start()
@ -163,10 +148,6 @@ class BoxService(
return
}
if (delayStart) {
delay(1000L)
}
newService.start()
if (newService.needWIFIState()) {
@ -203,7 +184,6 @@ class BoxService(
pfd.close()
fileDescriptor = null
}
commandServer?.setService(null)
boxService?.apply {
runCatching {
close()
@ -212,9 +192,11 @@ class BoxService(
}
Seq.destroyRef(refnum)
}
commandServer?.setService(null)
commandServer?.resetLog()
boxService = null
runBlocking {
startService(true)
startService()
}
}
@ -259,7 +241,6 @@ class BoxService(
pfd.close()
fileDescriptor = null
}
commandServer?.setService(null)
boxService?.apply {
runCatching {
close()
@ -268,6 +249,7 @@ class BoxService(
}
Seq.destroyRef(refnum)
}
commandServer?.setService(null)
boxService = null
Libbox.registerLocalDNSTransport(null)
DefaultNetworkMonitor.stop()
@ -309,7 +291,6 @@ class BoxService(
if (!receiverRegistered) {
ContextCompat.registerReceiver(service, receiver, IntentFilter().apply {
addAction(Action.SERVICE_CLOSE)
addAction(Action.SERVICE_RELOAD)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)
}
@ -344,9 +325,7 @@ class BoxService(
}
internal fun writeLog(message: String) {
binder.broadcast {
it.onServiceWriteLog(message)
}
commandServer?.writeMessage(message)
}
}

View file

@ -150,6 +150,11 @@ interface PlatformInterfaceWrapper : PlatformInterface {
private class StringArray(private val iterator: Iterator<String>) : StringIterator {
override fun len(): Int {
// not used by core
return 0
}
override fun hasNext(): Boolean {
return iterator.hasNext()
}

View file

@ -94,8 +94,6 @@ class ServiceConnection(
interface Callback {
fun onServiceStatusChanged(status: Status)
fun onServiceAlert(type: Alert, message: String?) {}
fun onServiceWriteLog(message: String?) {}
fun onServiceResetLogs(messages: MutableList<String>) {}
}
class ServiceCallback(private val callback: Callback) : IServiceCallback.Stub() {
@ -106,10 +104,5 @@ class ServiceConnection(
override fun onServiceAlert(type: Int, message: String?) {
callback.onServiceAlert(Alert.values()[type], message)
}
override fun onServiceWriteLog(message: String?) = callback.onServiceWriteLog(message)
override fun onServiceResetLogs(messages: MutableList<String>) =
callback.onServiceResetLogs(messages)
}
}

View file

@ -3,5 +3,4 @@ package io.nekohasekai.sfa.constant
object Action {
const val SERVICE = "io.nekohasekai.sfa.SERVICE"
const val SERVICE_CLOSE = "io.nekohasekai.sfa.SERVICE_CLOSE"
const val SERVICE_RELOAD = "io.nekohasekai.sfa.SERVICE_RELOAD"
}

View file

@ -11,6 +11,11 @@ fun Iterable<String>.toStringIterator(): StringIterator {
return object : StringIterator {
val iterator = iterator()
override fun len(): Int {
// not used by core
return 0
}
override fun hasNext(): Boolean {
return iterator.hasNext()
}

View file

@ -53,7 +53,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.Date
import java.util.LinkedList
class MainActivity : AbstractActivity<ActivityMainBinding>(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
@ -69,8 +68,6 @@ class MainActivity : AbstractActivity<ActivityMainBinding>(),
private val connection = ServiceConnection(this, this)
val logList = LinkedList<String>()
var logCallback: ((Boolean) -> Unit)? = null
val serviceStatus = MutableLiveData(Status.Stopped)
override fun onCreate(savedInstanceState: Bundle?) {
@ -436,43 +433,9 @@ class MainActivity : AbstractActivity<ActivityMainBinding>(),
}
}
private var paused = false
override fun onPause() {
super.onPause()
paused = true
}
override fun onResume() {
super.onResume()
paused = false
logCallback?.invoke(true)
}
override fun onServiceWriteLog(message: String?) {
if (paused) {
if (logList.size > 300) {
logList.removeFirst()
}
}
logList.addLast(message)
if (!paused) {
logCallback?.invoke(false)
}
}
override fun onServiceResetLogs(messages: MutableList<String>) {
logList.clear()
logList.addAll(messages)
if (!paused) logCallback?.invoke(true)
}
override fun onDestroy() {
connection.disconnect()
super.onDestroy()
}
}

View file

@ -107,17 +107,27 @@ class OverviewFragment : Fragment() {
val status = Libbox.newStandaloneCommandClient().systemProxyStatus
withContext(Dispatchers.Main) {
binding.systemProxyCard.isVisible = status.available
binding.systemProxySwitch.setOnClickListener(null)
binding.systemProxySwitch.setOnCheckedChangeListener(null)
binding.systemProxySwitch.isChecked = status.enabled
binding.systemProxySwitch.isEnabled = true
var reloading = false
binding.systemProxySwitch.setOnCheckedChangeListener { buttonView, isChecked ->
binding.systemProxySwitch.isEnabled = false
lifecycleScope.launch(Dispatchers.IO) {
Settings.systemProxyEnabled = isChecked
runCatching {
Libbox.newStandaloneCommandClient().setSystemProxyEnabled(isChecked)
}.onFailure {
buttonView.context.errorDialogBuilder(it).show()
synchronized(this@OverviewFragment) {
if (reloading) return@setOnCheckedChangeListener
reloading = true
binding.systemProxySwitch.isEnabled = false
lifecycleScope.launch(Dispatchers.IO) {
Settings.systemProxyEnabled = isChecked
runCatching {
Libbox.newStandaloneCommandClient().setSystemProxyEnabled(isChecked)
}.onFailure {
withContext(Dispatchers.Main) {
buttonView.context.errorDialogBuilder(it).show()
}
}
withContext(Dispatchers.Main) {
delay(1000L)
binding.systemProxySwitch.isEnabled = true
}
}
}
}

View file

@ -52,6 +52,7 @@ class DashboardFragment : Fragment(R.layout.fragment_dashboard) {
enablePager()
binding.fab.setImageResource(R.drawable.ic_stop_24)
binding.fab.show()
binding.fab.isEnabled = true
}
Status.Stopping -> {
@ -65,6 +66,7 @@ class DashboardFragment : Fragment(R.layout.fragment_dashboard) {
binding.fab.setOnClickListener {
when (activity.serviceStatus.value) {
Status.Stopped -> {
it.isEnabled = false
activity.startService()
}

View file

@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.nekohasekai.sfa.R
@ -15,12 +16,18 @@ import io.nekohasekai.sfa.databinding.FragmentLogBinding
import io.nekohasekai.sfa.databinding.ViewLogTextItemBinding
import io.nekohasekai.sfa.ui.MainActivity
import io.nekohasekai.sfa.utils.ColorUtils
import io.nekohasekai.sfa.utils.CommandClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.LinkedList
class LogFragment : Fragment() {
class LogFragment : Fragment(), CommandClient.Handler {
private val activity: MainActivity? get() = super.getActivity() as MainActivity?
private var binding: FragmentLogBinding? = null
private var logAdapter: LogAdapter? = null
private var adapter: Adapter? = null
private val commandClient =
CommandClient(lifecycleScope, CommandClient.ConnectionType.Log, this)
private val logList = LinkedList<String>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@ -34,10 +41,9 @@ class LogFragment : Fragment() {
private fun onCreate() {
val activity = activity ?: return
val binding = binding ?: return
activity.logCallback = ::updateViews
binding.logView.layoutManager = LinearLayoutManager(requireContext())
binding.logView.adapter = LogAdapter(activity.logList).also { logAdapter = it }
updateViews(true)
binding.logView.adapter = Adapter(logList).also { adapter = it }
updateViews()
activity.serviceStatus.observe(viewLifecycleOwner) {
when (it) {
Status.Stopped -> {
@ -52,8 +58,10 @@ class LogFragment : Fragment() {
}
Status.Started -> {
commandClient.connect()
binding.fab.setImageResource(R.drawable.ic_stop_24)
binding.fab.show()
binding.fab.isEnabled = true
binding.statusText.setText(R.string.status_started)
}
@ -68,6 +76,7 @@ class LogFragment : Fragment() {
binding.fab.setOnClickListener {
when (activity.serviceStatus.value) {
Status.Stopped -> {
it.isEnabled = false
activity.startService()
}
@ -80,34 +89,68 @@ class LogFragment : Fragment() {
}
}
private fun updateViews(reset: Boolean) {
private fun updateViews(removeLen: Int = 0, insertLen: Int = 0) {
val activity = activity ?: return
val logAdapter = logAdapter ?: return
val logAdapter = adapter ?: return
val binding = binding ?: return
if (activity.logList.isEmpty()) {
if (logList.isEmpty()) {
binding.logView.isVisible = false
binding.statusText.isVisible = true
} else if (!binding.logView.isVisible) {
binding.logView.isVisible = true
binding.statusText.isVisible = false
}
if (reset) {
if (insertLen == 0) {
logAdapter.notifyDataSetChanged()
binding.logView.scrollToPosition(activity.logList.size - 1)
if (logList.size > 0) {
binding.logView.scrollToPosition(logList.size - 1)
}
} else {
binding.logView.scrollToPosition(logAdapter.notifyItemInserted())
if (logList.size == 300) {
logAdapter.notifyItemRangeRemoved(0, removeLen)
}
logAdapter.notifyItemRangeInserted(logList.size - insertLen, insertLen)
binding.logView.scrollToPosition(logList.size - 1)
}
}
override fun onDestroyView() {
super.onDestroyView()
commandClient.disconnect()
binding = null
activity?.logCallback = null
logAdapter = null
adapter = null
}
override fun onConnected() {
lifecycleScope.launch(Dispatchers.Main) {
logList.clear()
updateViews()
}
}
override fun clearLogs() {
lifecycleScope.launch(Dispatchers.Main) {
logList.clear()
updateViews()
}
}
override fun appendLogs(messageList: List<String>) {
lifecycleScope.launch(Dispatchers.Main) {
val messageLen = messageList.size
val removeLen = logList.size + messageLen - 300
if (removeLen > 0) {
repeat(removeLen) {
logList.removeFirst()
}
}
logList.addAll(messageList)
updateViews(removeLen, messageLen)
}
}
class LogAdapter(private val logList: LinkedList<String>) :
class Adapter(private val logList: LinkedList<String>) :
RecyclerView.Adapter<LogViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LogViewHolder {
return LogViewHolder(
@ -125,17 +168,6 @@ class LogFragment : Fragment() {
return logList.size
}
fun notifyItemInserted(): Int {
if (logList.size > 300) {
logList.removeFirst()
notifyItemRemoved(0)
}
val position = logList.size - 1
notifyItemInserted(position)
return position
}
}
class LogViewHolder(private val binding: ViewLogTextItemBinding) :

View file

@ -33,8 +33,8 @@ open class CommandClient(
fun onDisconnected() {}
fun updateStatus(status: StatusMessage) {}
fun updateGroups(newGroups: MutableList<OutboundGroup>) {}
fun clearLog() {}
fun appendLog(message: String) {}
fun clearLogs() {}
fun appendLogs(message: List<String>) {}
fun initializeClashMode(modeList: List<String>, currentMode: String) {}
fun updateClashMode(newMode: String) {}
@ -108,15 +108,15 @@ open class CommandClient(
handler.updateGroups(groups)
}
override fun clearLog() {
handler.clearLog()
override fun clearLogs() {
handler.clearLogs()
}
override fun writeLog(message: String?) {
if (message == null) {
override fun writeLogs(messageList: StringIterator?) {
if (messageList == null) {
return
}
handler.appendLog(message)
handler.appendLogs(messageList.toList())
}
override fun writeStatus(message: StatusMessage?) {