Skip to content

Commit 5893f2e

Browse files
committed
feat: refactor event dispatcher
1 parent 093b4c0 commit 5893f2e

4 files changed

Lines changed: 102 additions & 69 deletions

File tree

android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
99
import com.aheaditec.talsec_security.security.api.Talsec
1010
import com.aheaditec.talsec_security.security.api.TalsecConfig
1111
import com.aheaditec.talsec_security.security.api.TalsecMode
12-
import com.aheaditec.talsec_security.security.api.ThreatListener
1312
import com.facebook.react.bridge.Arguments
1413
import com.facebook.react.bridge.LifecycleEventListener
1514
import com.facebook.react.bridge.Promise
@@ -19,8 +18,8 @@ import com.facebook.react.bridge.ReactMethod
1918
import com.facebook.react.bridge.ReadableMap
2019
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
2120
import com.facebook.react.bridge.WritableArray
21+
import com.facebook.react.bridge.WritableMap
2222
import com.facebook.react.modules.core.DeviceEventManagerModule
23-
import com.freeraspreactnative.events.BaseRaspEvent
2423
import com.freeraspreactnative.events.RaspExecutionStateEvent
2524
import com.freeraspreactnative.events.ThreatEvent
2625
import com.freeraspreactnative.interfaces.PluginExecutionStateListener
@@ -38,19 +37,25 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
3837

3938
private val lifecycleListener = object : LifecycleEventListener {
4039
override fun onHostResume() {
40+
PluginThreatHandler.threatDispatcher.onResume()
41+
PluginThreatHandler.executionStateDispatcher.onResume()
4142
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
4243
reactContext.currentActivity?.let { ScreenProtector.register(it) }
4344
}
4445
}
4546

4647
override fun onHostPause() {
48+
PluginThreatHandler.threatDispatcher.onPause()
49+
PluginThreatHandler.executionStateDispatcher.onPause()
4750
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
4851
reactContext.currentActivity?.let { ScreenProtector.unregister(it) }
4952
}
5053
}
5154

5255
override fun onHostDestroy() {
5356
backgroundHandlerThread.quitSafely()
57+
PluginThreatHandler.threatDispatcher.unregisterListener()
58+
PluginThreatHandler.executionStateDispatcher.unregisterListener()
5459
}
5560
}
5661

@@ -61,6 +66,7 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
6166
init {
6267
reactContext.addLifecycleEventListener(lifecycleListener)
6368
initializeEventKeys()
69+
PluginThreatHandler.initializeDispatchers(PluginListener(reactContext))
6470
}
6571

6672
@ReactMethod
@@ -149,10 +155,10 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
149155
@ReactMethod
150156
fun addListener(eventName: String) {
151157
if (eventName == ThreatEvent.CHANNEL_NAME) {
152-
PluginThreatHandler.threatDispatcher.listener = PluginListener(reactContext)
158+
PluginThreatHandler.threatDispatcher.registerListener()
153159
}
154160
if (eventName == RaspExecutionStateEvent.CHANNEL_NAME) {
155-
PluginThreatHandler.executionStateDispatcher.listener = PluginListener(reactContext)
161+
PluginThreatHandler.executionStateDispatcher.registerListener()
156162
}
157163
}
158164

@@ -165,10 +171,10 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
165171
@ReactMethod
166172
fun removeListenerForEvent(eventName: String, promise: Promise) {
167173
if (eventName == ThreatEvent.CHANNEL_NAME) {
168-
PluginThreatHandler.threatDispatcher.listener = null
174+
PluginThreatHandler.threatDispatcher.unregisterListener()
169175
}
170176
if (eventName == RaspExecutionStateEvent.CHANNEL_NAME) {
171-
PluginThreatHandler.executionStateDispatcher.listener = null
177+
PluginThreatHandler.executionStateDispatcher.unregisterListener()
172178
}
173179
promise.resolve("Listener unregistered")
174180
}
@@ -302,48 +308,40 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
302308
private val mainHandler = Handler(Looper.getMainLooper())
303309

304310
internal var talsecStarted = false
311+
}
312+
313+
internal class PluginListener(private val reactContext: ReactApplicationContext) :
314+
PluginThreatListener, PluginExecutionStateListener {
305315

306-
private fun notifyEvent(event: BaseRaspEvent, appReactContext: ReactApplicationContext) {
316+
override fun threatDetected(threatEventType: ThreatEvent) {
307317
val params = Arguments.createMap()
308-
params.putInt(event.channelKey, event.value)
309-
appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
310-
.emit(event.channelName, params)
318+
params.putInt(threatEventType.channelKey, threatEventType.value)
319+
notifyEvent(ThreatEvent.CHANNEL_NAME, params)
311320
}
312321

313-
/**
314-
* Sends malware detected event to React Native
315-
*/
316-
private fun notifyMalware(suspiciousApps: MutableList<SuspiciousAppInfo>, appReactContext: ReactApplicationContext) {
317-
// Perform the malware encoding on a background thread
322+
override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
318323
backgroundHandler.post {
319-
320-
val encodedSuspiciousApps = suspiciousApps.toEncodedWritableArray(appReactContext)
321-
324+
val encodedSuspiciousApps = suspiciousApps.toEncodedWritableArray(reactContext)
322325
mainHandler.post {
323326
val params = Arguments.createMap()
324327
params.putInt(ThreatEvent.CHANNEL_KEY, ThreatEvent.Malware.value)
325328
params.putArray(
326329
ThreatEvent.MALWARE_CHANNEL_KEY, encodedSuspiciousApps
327330
)
328-
329-
appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
330-
.emit(ThreatEvent.CHANNEL_NAME, params)
331+
notifyEvent(ThreatEvent.CHANNEL_NAME, params)
331332
}
332333
}
333334
}
334-
}
335335

336-
internal class PluginListener(private val reactContext: ReactApplicationContext) : PluginThreatListener, PluginExecutionStateListener {
337-
override fun threatDetected(threatEventType: ThreatEvent) {
338-
notifyEvent(threatEventType, reactContext)
339-
}
340-
341-
override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
342-
notifyMalware(suspiciousApps, reactContext)
336+
override fun raspExecutionStateChanged(event: RaspExecutionStateEvent) {
337+
val params = Arguments.createMap()
338+
params.putInt(event.channelKey, event.value)
339+
notifyEvent(event.channelName, params)
343340
}
344341

345-
override fun raspExecutionStateChanged(event: RaspExecutionStateEvent) {
346-
notifyEvent(event, reactContext)
342+
private fun notifyEvent(eventName: String, params: WritableMap) {
343+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
344+
.emit(eventName, params)
347345
}
348346
}
349-
}
347+
}

android/src/main/java/com/freeraspreactnative/PluginThreatHandler.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ import com.freeraspreactnative.events.ThreatEvent
1010

1111
internal object PluginThreatHandler {
1212

13-
internal val threatDispatcher = ThreatDispatcher()
14-
internal val executionStateDispatcher = ExecutionStateDispatcher()
13+
internal lateinit var threatDispatcher: ThreatDispatcher
14+
internal lateinit var executionStateDispatcher: ExecutionStateDispatcher
15+
16+
fun initializeDispatchers(listener: FreeraspReactNativeModule.PluginListener) {
17+
threatDispatcher = ThreatDispatcher(listener)
18+
executionStateDispatcher = ExecutionStateDispatcher(listener)
19+
}
1520

1621
private val threatDetected = object : ThreatListener.ThreatDetected() {
1722

android/src/main/java/com/freeraspreactnative/dispatchers/ExecutionStateDispatcher.kt

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,52 @@ package com.freeraspreactnative.dispatchers
33
import com.freeraspreactnative.events.RaspExecutionStateEvent
44
import com.freeraspreactnative.interfaces.PluginExecutionStateListener
55

6-
internal class ExecutionStateDispatcher {
6+
internal class ExecutionStateDispatcher(private val listener: PluginExecutionStateListener) {
77
private val cache = mutableSetOf<RaspExecutionStateEvent>()
88

9-
var listener: PluginExecutionStateListener? = null
10-
set(value) {
11-
field = value
12-
if (value != null) {
13-
flushCache(value)
14-
}
9+
private var isAppInForeground = false
10+
private var isListenerRegistered = false
11+
12+
fun registerListener() {
13+
isListenerRegistered = true
14+
isAppInForeground = true
15+
flushCache()
16+
}
17+
18+
fun unregisterListener() {
19+
isListenerRegistered = false
20+
isAppInForeground = false
21+
}
22+
23+
fun onResume() {
24+
isAppInForeground = true
25+
if (isListenerRegistered) {
26+
flushCache()
1527
}
28+
29+
}
30+
31+
fun onPause() {
32+
isAppInForeground = false
33+
}
1634

1735
fun dispatch(event: RaspExecutionStateEvent) {
18-
val currentListener = listener
19-
if (currentListener != null) {
20-
currentListener.raspExecutionStateChanged(event)
36+
if (isAppInForeground && isListenerRegistered) {
37+
listener.raspExecutionStateChanged(event)
2138
} else {
2239
synchronized(cache) {
23-
val checkedListener = listener
24-
checkedListener?.raspExecutionStateChanged(event) ?: cache.add(event)
40+
cache.add(event)
2541
}
2642
}
2743
}
2844

29-
private fun flushCache(registeredListener: PluginExecutionStateListener) {
45+
private fun flushCache() {
3046
val events = synchronized(cache) {
3147
val snapshot = cache.toSet()
3248
cache.clear()
3349
snapshot
3450
}
35-
events.forEach { registeredListener.raspExecutionStateChanged(it) }
51+
events.forEach { listener.raspExecutionStateChanged(it) }
3652
}
3753
}
3854

android/src/main/java/com/freeraspreactnative/dispatchers/ThreatDispatcher.kt

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,71 @@ import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
44
import com.freeraspreactnative.events.ThreatEvent
55
import com.freeraspreactnative.interfaces.PluginThreatListener
66

7-
internal class ThreatDispatcher {
7+
internal class ThreatDispatcher(private val listener: PluginThreatListener) {
88
private val threatCache = mutableSetOf<ThreatEvent>()
99
private val malwareCache = mutableSetOf<SuspiciousAppInfo>()
1010

11-
var listener: PluginThreatListener? = null
12-
set(value) {
13-
field = value
14-
if (value != null) {
15-
flushCache(value)
16-
}
11+
private var isAppInForeground = false
12+
private var isListenerRegistered = false
13+
14+
fun registerListener() {
15+
isListenerRegistered = true
16+
isAppInForeground = true
17+
flushCache()
18+
}
19+
20+
fun unregisterListener() {
21+
isListenerRegistered = false
22+
isAppInForeground = false
23+
}
24+
25+
fun onResume() {
26+
isAppInForeground = true
27+
if (isListenerRegistered) {
28+
flushCache()
1729
}
30+
}
31+
32+
fun onPause() {
33+
isAppInForeground = false
34+
}
1835

1936
fun dispatchThreat(event: ThreatEvent) {
20-
val currentListener = listener
21-
if (currentListener != null) {
22-
currentListener.threatDetected(event)
37+
if (isAppInForeground && isListenerRegistered) {
38+
listener.threatDetected(event)
2339
} else {
2440
synchronized(threatCache) {
25-
val checkedListener = listener
26-
checkedListener?.threatDetected(event) ?: threatCache.add(event)
41+
threatCache.add(event)
2742
}
2843
}
2944
}
3045

3146
fun dispatchMalware(apps: MutableList<SuspiciousAppInfo>) {
32-
val currentListener = listener
33-
if (currentListener != null) {
34-
currentListener.malwareDetected(apps)
35-
} else {
47+
if (isAppInForeground) {
48+
listener.malwareDetected(apps)
49+
}
50+
else {
3651
synchronized(malwareCache) {
37-
val checkedListener = listener
38-
checkedListener?.malwareDetected(apps) ?: malwareCache.addAll(apps)
52+
malwareCache.addAll(apps)
3953
}
4054
}
4155
}
4256

43-
private fun flushCache(registeredListener: PluginThreatListener) {
57+
private fun flushCache() {
4458
val threats = synchronized(threatCache) {
4559
val snapshot = threatCache.toSet()
4660
threatCache.clear()
4761
snapshot
4862
}
49-
threats.forEach { registeredListener.threatDetected(it) }
63+
threats.forEach { listener.threatDetected(it) }
5064

5165
val malware = synchronized(malwareCache) {
5266
val snapshot = malwareCache.toMutableList()
5367
malwareCache.clear()
5468
snapshot
5569
}
5670
if (malware.isNotEmpty()) {
57-
registeredListener.malwareDetected(malware)
71+
listener.malwareDetected(malware)
5872
}
5973
}
6074
}

0 commit comments

Comments
 (0)