event framework
This commit is contained in:
11 files changed
+258
-22
No files matched your search
@@ -0,0 +1,31 @@
|
||||
package com.github.kr328.clash.core.event
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ErrorEvent(val type: Type, val message: String): Event, Parcelable {
|
||||
enum class Type {
|
||||
|
||||
}
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<ErrorEvent> {
|
||||
override fun createFromParcel(parcel: Parcel): ErrorEvent {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<ErrorEvent?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.github.kr328.clash.core.event
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Decoder
|
||||
import kotlinx.serialization.Encoder
|
||||
import kotlinx.serialization.KSerializer
|
||||
@@ -10,12 +13,23 @@ import java.lang.IllegalArgumentException
|
||||
|
||||
@Serializable
|
||||
data class LogEvent(val level: Level, val message: String):
|
||||
Event {
|
||||
Event, Parcelable {
|
||||
companion object {
|
||||
const val DEBUG_VALUE = 1
|
||||
const val INFO_VALUE = 2
|
||||
const val WARN_VALUE = 3
|
||||
const val ERROR_VALUE = 4
|
||||
|
||||
@JvmField
|
||||
val CREATOR = object: Parcelable.Creator<LogEvent> {
|
||||
override fun createFromParcel(parcel: Parcel): LogEvent {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<LogEvent?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable(LevelSerializer::class)
|
||||
@@ -45,4 +59,12 @@ data class LogEvent(val level: Level, val message: String):
|
||||
encoder.encodeInt(obj.value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,28 @@
|
||||
package com.github.kr328.clash.core.event
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.github.kr328.clash.core.event.Event
|
||||
import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
class ProxyChangedEvent : Event
|
||||
@Serializable
|
||||
data class ProxyChangedEvent(val name: String, val selected: String) : Event,Parcelable {
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<ProxyChangedEvent> {
|
||||
override fun createFromParcel(parcel: Parcel): ProxyChangedEvent {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<ProxyChangedEvent?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,27 @@
|
||||
package com.github.kr328.clash.core.event
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class TrafficEvent(val down: Long, val up: Long, val total: Long): Event
|
||||
data class TrafficEvent(val down: Long, val up: Long, val total: Long): Event, Parcelable {
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<TrafficEvent> {
|
||||
override fun createFromParcel(parcel: Parcel): TrafficEvent {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<TrafficEvent?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
package com.github.kr328.clash.core;
|
||||
|
||||
parcelable ClashProcessStatus;
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.github.kr328.clash.core.event;
|
||||
|
||||
parcelable ProcessEvent;
|
||||
parcelable LogEvent;
|
||||
parcelable ProxyChangedEvent;
|
||||
parcelable TrafficEvent;
|
||||
parcelable ErrorEvent;
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
import com.github.kr328.clash.core.event.Event;
|
||||
|
||||
interface IClashEventObserver {
|
||||
void onProcessEvent(in ProcessEvent event);
|
||||
void onProxyChangedEvent(in ProxyChangedEvent event);
|
||||
void onLogEvent(in LogEvent event);
|
||||
void onErrorEvent(in ErrorEvent event);
|
||||
void onTrafficEvent(in TrafficEvent event);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
import com.github.kr328.clash.service.IClashEventObserver;
|
||||
|
||||
interface IClashEventService {
|
||||
void registerEventObserver(String id, in IClashEventObserver observer);
|
||||
void unregisterEventObserver(String id);
|
||||
|
||||
void acquireEvent(String id, int event);
|
||||
void releaseEvent(String id, int event);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
import com.github.kr328.clash.core.model.ClashProcessStatus;
|
||||
|
||||
interface IClashObserver {
|
||||
void onProxyChanged();
|
||||
void onNewLogItem();
|
||||
void onProcessStatusChanged(in ClashProcessStatus status);
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
import com.github.kr328.clash.service.IClashObserver;
|
||||
import com.github.kr328.clash.core.model.ClashProcessStatus;
|
||||
import com.github.kr328.clash.service.IClashEventObserver;
|
||||
import com.github.kr328.clash.service.IClashEventService;
|
||||
import com.github.kr328.clash.core.event.Event;
|
||||
|
||||
interface IClashService {
|
||||
void start();
|
||||
void stop();
|
||||
ClashProcessStatus getClashProcessStatus();
|
||||
void registerObserver(String id, boolean notifyCurrent, in IClashObserver observer);
|
||||
void unregisterObserver(String id);
|
||||
IClashEventService getEventService();
|
||||
void startTunDevice(in ParcelFileDescriptor fd, int mtu);
|
||||
void stopTunDevice();
|
||||
void start();
|
||||
void stop();
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.github.kr328.clash.service
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.github.kr328.clash.core.event.*
|
||||
import java.util.*
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ClashEventService(private val master: Master) : IClashEventService.Stub() {
|
||||
interface Master {
|
||||
fun requireEvent(event: Int)
|
||||
fun releaseEvent(event: Int)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EVENT_SET = setOf(Event.EVENT_LOG, Event.EVENT_TRAFFIC, Event.EVENT_PROXY_CHANGED)
|
||||
}
|
||||
|
||||
private data class EventObserverRecord(val observer: IClashEventObserver, val acquiredEvent: MutableSet<Int>)
|
||||
|
||||
private val observers = mutableMapOf<String, EventObserverRecord>()
|
||||
private lateinit var handler: Handler
|
||||
|
||||
init {
|
||||
thread {
|
||||
Looper.prepare()
|
||||
|
||||
handler = Handler()
|
||||
|
||||
Looper.loop()
|
||||
}
|
||||
}
|
||||
|
||||
fun preformProcessEvent(event: ProcessEvent) {
|
||||
handler.post {
|
||||
observers.values.forEach {
|
||||
it.observer.onProcessEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun preformLogEvent(event: LogEvent) {
|
||||
handler.post {
|
||||
observers.values.forEach {
|
||||
it.observer.onLogEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun preformProxyChangedEvent(event: ProxyChangedEvent) {
|
||||
handler.post {
|
||||
observers.values.forEach {
|
||||
it.observer.onProxyChangedEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun preformTrafficEvent(event: TrafficEvent) {
|
||||
handler.post {
|
||||
observers.values.forEach {
|
||||
it.observer.onTrafficEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun preformErrorEvent(event: ErrorEvent) {
|
||||
handler.post {
|
||||
observers.values.forEach {
|
||||
it.observer.onErrorEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun acquireEvent(id: String?, event: Int) {
|
||||
handler.post {
|
||||
require(id != null)
|
||||
|
||||
observers[id]?.acquiredEvent?.add(event)
|
||||
|
||||
recastEventRequirement()
|
||||
}
|
||||
}
|
||||
|
||||
override fun releaseEvent(id: String?, event: Int) {
|
||||
handler.post {
|
||||
require(id != null)
|
||||
|
||||
observers[id]?.acquiredEvent?.remove(event)
|
||||
|
||||
recastEventRequirement()
|
||||
}
|
||||
}
|
||||
|
||||
override fun unregisterEventObserver(id: String?) {
|
||||
handler.post {
|
||||
require(id != null)
|
||||
|
||||
observers.remove(id)
|
||||
|
||||
recastEventRequirement()
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerEventObserver(id: String?, observer: IClashEventObserver?) {
|
||||
handler.post {
|
||||
require(id != null && observer != null)
|
||||
|
||||
observers[id] = EventObserverRecord(observer, mutableSetOf())
|
||||
}
|
||||
}
|
||||
|
||||
fun recastEventRequirement() {
|
||||
handler.post {
|
||||
val req = observers.values.flatMap {
|
||||
it.acquiredEvent
|
||||
}.toSet()
|
||||
val rel = EVENT_SET - req
|
||||
|
||||
req.forEach(master::requireEvent)
|
||||
rel.forEach(master::releaseEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user