add log
This commit is contained in:
10 files changed
+209
-19
No files matched your search
@@ -74,7 +74,11 @@
|
||||
android:label="@string/application_setting_application"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".LogActivity"
|
||||
android:label="@string/clash_logs"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
<service
|
||||
android:name=".ClashStartService"
|
||||
android:exported="false" />
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import androidx.collection.CircularArray
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.adapter.LogAdapter
|
||||
import com.github.kr328.clash.core.event.Event
|
||||
import com.github.kr328.clash.core.event.LogEvent
|
||||
import com.github.kr328.clash.core.utils.Log
|
||||
import kotlinx.android.synthetic.main.activity_logs.*
|
||||
|
||||
|
||||
class LogActivity : BaseActivity() {
|
||||
companion object {
|
||||
const val MAX_EVENT_COUNT = 100
|
||||
}
|
||||
|
||||
private var syncLog = false
|
||||
private val buffer = CircularArray<LogEvent>(MAX_EVENT_COUNT)
|
||||
private val handler = Handler()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_logs)
|
||||
|
||||
setSupportActionBar(activity_logs_toolbar)
|
||||
|
||||
activity_logs_list.also {
|
||||
val dividerItemDecoration = DividerItemDecoration(
|
||||
this,
|
||||
DividerItemDecoration.VERTICAL
|
||||
)
|
||||
it.addItemDecoration(dividerItemDecoration)
|
||||
|
||||
it.adapter = LogAdapter(this, buffer)
|
||||
it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
syncLog = true
|
||||
|
||||
activity_logs_list.adapter?.notifyDataSetChanged()
|
||||
|
||||
runClash {
|
||||
it.eventService.registerEventObserver(LogActivity::class.java.name,
|
||||
this,
|
||||
intArrayOf(Event.EVENT_LOG))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
syncLog = false
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
runClash {
|
||||
it.eventService.unregisterEventObserver(LogActivity::class.java.name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLogEvent(event: LogEvent?) {
|
||||
handler.post {
|
||||
buffer.addFirst(event)
|
||||
|
||||
if ( syncLog ) {
|
||||
activity_logs_list.adapter!!.notifyItemInserted(0)
|
||||
if ( activity_logs_list.computeVerticalScrollOffset() < 30 )
|
||||
activity_logs_list.scrollToPosition(0)
|
||||
}
|
||||
|
||||
if ( buffer.size() >= MAX_EVENT_COUNT ) {
|
||||
buffer.removeFromEnd(buffer.size() - MAX_EVENT_COUNT - 1)
|
||||
|
||||
if ( syncLog ) {
|
||||
activity_logs_list.adapter?.notifyItemRangeRemoved(MAX_EVENT_COUNT - 1,
|
||||
buffer.size() - MAX_EVENT_COUNT - 1 )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,10 @@ class MainActivity : BaseActivity() {
|
||||
startActivity(Intent(this, SettingMainActivity::class.java))
|
||||
}
|
||||
|
||||
activity_main_clash_logs.setOnClickListener {
|
||||
startActivity(Intent(this, LogActivity::class.java))
|
||||
}
|
||||
|
||||
activity_main_clash_status_icon.setImageResource(R.drawable.ic_clash_stopped)
|
||||
activity_main_clash_status_title.text = getString(R.string.clash_status_stopped)
|
||||
activity_main_clash_status_summary.text = getString(R.string.clash_status_click_to_start)
|
||||
|
||||
@@ -43,8 +43,6 @@ class ProxyActivity : BaseActivity() {
|
||||
.toMap()
|
||||
|
||||
for ((_, p) in proxies) {
|
||||
Log.i("$p -> ${p.index}")
|
||||
|
||||
p.value.delay = -1
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.github.kr328.clash.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.collection.CircularArray
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.R
|
||||
import com.github.kr328.clash.core.event.LogEvent
|
||||
import kotlinx.android.synthetic.main.adapter_log.view.*
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class LogAdapter(private val content: Context,
|
||||
private val buffer: CircularArray<LogEvent>) : RecyclerView.Adapter<LogAdapter.Holder>() {
|
||||
private val formatter = SimpleDateFormat("hh:MM:ss", Locale.getDefault())
|
||||
|
||||
class Holder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val type: TextView = view.findViewById(R.id.adapter_log_type)
|
||||
val time: TextView = view.findViewById(R.id.adapter_log_time)
|
||||
val content: TextView = view.findViewById(R.id.adapter_log_content)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
|
||||
return Holder(LayoutInflater.from(content)
|
||||
.inflate(R.layout.adapter_log, parent, false))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return buffer.size()
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: Holder, position: Int) {
|
||||
val current = buffer.get(position)
|
||||
|
||||
holder.type.text = current.level.toString()
|
||||
holder.time.text = formatter.format(Date(current.time))
|
||||
holder.content.text = current.message
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/activity_logs_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp">
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:id="@+id/activity_logs_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp">
|
||||
<TextView
|
||||
android:textColor="@color/colorAccent"
|
||||
android:id="@+id/adapter_log_type"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:layout_toStartOf="@id/adapter_log_time"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/adapter_log_time"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"/>
|
||||
|
||||
<TextView
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_below="@id/adapter_log_type"
|
||||
android:id="@+id/adapter_log_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
@@ -18,17 +18,16 @@ func handlePullTrafficEvent(client *net.UnixConn) {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
defer ticker.Stop()
|
||||
defer client.Close()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
var buf [4]byte
|
||||
|
||||
_, err := client.Read(buf[:])
|
||||
client.Read(buf[:])
|
||||
|
||||
if err != nil {
|
||||
close(trafficExit)
|
||||
return
|
||||
}
|
||||
close(trafficExit)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -68,17 +67,16 @@ func handlePullBandwidthEvent(client *net.UnixConn) {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
defer ticker.Stop()
|
||||
defer client.Close()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
var buf [4]byte
|
||||
|
||||
_, err := client.Read(buf[:])
|
||||
client.Read(buf[:])
|
||||
|
||||
if err != nil {
|
||||
close(bandWidthExit)
|
||||
return
|
||||
}
|
||||
close(bandWidthExit)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -118,16 +116,18 @@ func handlePullLogEvent(client *net.UnixConn) {
|
||||
subseribe := log.Subscribe()
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
defer log.UnSubscribe(subseribe)
|
||||
defer client.Close()
|
||||
|
||||
go func() {
|
||||
var buf [4]byte
|
||||
|
||||
for {
|
||||
_, err := client.Read(buf[:])
|
||||
client.Read(buf[:])
|
||||
|
||||
if err != nil {
|
||||
close(logExit)
|
||||
return
|
||||
}
|
||||
logExit <- 0
|
||||
close(logExit)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import kotlinx.serialization.*
|
||||
import kotlinx.serialization.internal.StringDescriptor
|
||||
|
||||
@Serializable
|
||||
data class LogEvent(val level: Level, val message: String) :
|
||||
data class LogEvent(val level: Level, val message: String, val time: Long = System.currentTimeMillis()) :
|
||||
Event, Parcelable {
|
||||
companion object {
|
||||
const val DEBUG_VALUE = 1
|
||||
|
||||
@@ -127,6 +127,7 @@ class ClashEventPuller(private val clash: Clash, private val master: Master) {
|
||||
|
||||
private fun LocalSocket?.closeSilent() {
|
||||
runCatching {
|
||||
this?.outputStream?.write(0)
|
||||
this?.close()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user