Skip to content

Commit 5ff15cb

Browse files
committed
Simplify message handling APIs
1 parent fc41ae7 commit 5ff15cb

File tree

8 files changed

+85
-66
lines changed

8 files changed

+85
-66
lines changed

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserWebViewClientTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.Unavailab
8585
import com.duckduckgo.feature.toggles.api.Toggle
8686
import com.duckduckgo.history.api.NavigationHistory
8787
import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScriptPlugin
88-
import com.duckduckgo.js.messaging.api.JsMessageCallback
8988
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
9089
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
9190
import com.duckduckgo.privacy.config.api.AmpLinks

app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,9 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.DuckPlayerState.ENABLED
7979
import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.On
8080
import com.duckduckgo.duckplayer.impl.DUCK_PLAYER_OPEN_IN_YOUTUBE_PATH
8181
import com.duckduckgo.history.api.NavigationHistory
82-
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
8382
import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScriptPlugin
84-
import com.duckduckgo.js.messaging.api.JsMessageCallback
8583
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
84+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
8685
import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed
8786
import com.duckduckgo.privacy.config.api.AmpLinks
8887
import com.duckduckgo.subscriptions.api.Subscriptions

content-scope-scripts/content-scope-scripts-impl/src/main/java/com/duckduckgo/contentscopescripts/impl/messaging/DebugFlagGlobalHandler.kt

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ package com.duckduckgo.contentscopescripts.impl.messaging
1818

1919
import com.duckduckgo.di.scopes.AppScope
2020
import com.duckduckgo.js.messaging.api.JsMessage
21-
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
21+
import com.duckduckgo.js.messaging.api.ProcessResult
22+
import com.duckduckgo.js.messaging.api.ProcessResult.SendToConsumer
2223
import com.squareup.anvil.annotations.ContributesMultibinding
2324
import javax.inject.Inject
2425
import logcat.logcat
25-
import org.json.JSONObject
2626

2727
@ContributesMultibinding(AppScope::class)
2828
class DebugFlagGlobalHandler @Inject constructor() : GlobalContentScopeJsMessageHandlersPlugin {
@@ -32,19 +32,12 @@ class DebugFlagGlobalHandler @Inject constructor() : GlobalContentScopeJsMessage
3232

3333
override fun process(
3434
jsMessage: JsMessage,
35-
jsMessageCallback: WebViewCompatMessageCallback,
36-
onResponse: (JSONObject) -> Unit,
37-
) {
35+
): ProcessResult? {
3836
if (jsMessage.method == method) {
3937
logcat { "DebugFlagGlobalHandler addDebugFlag: ${jsMessage.featureName}" }
40-
jsMessageCallback.process(
41-
featureName = jsMessage.featureName,
42-
method = jsMessage.method,
43-
id = jsMessage.id,
44-
data = jsMessage.params,
45-
onResponse = onResponse,
46-
)
38+
return SendToConsumer
4739
}
40+
return null
4841
}
4942

5043
override val method: String = "addDebugFlag"

content-scope-scripts/content-scope-scripts-impl/src/main/java/com/duckduckgo/contentscopescripts/impl/messaging/GlobalContentScopeJsMessageHandlersPlugin.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
package com.duckduckgo.contentscopescripts.impl.messaging
1818

1919
import com.duckduckgo.js.messaging.api.JsMessage
20-
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
21-
import org.json.JSONObject
20+
import com.duckduckgo.js.messaging.api.ProcessResult
2221

2322
/**
2423
* Plugin interface for global message handlers that should always be processed
@@ -45,13 +44,10 @@ interface GlobalJsMessageHandler {
4544
* invoking a callback so consumers can also process the message if needed.
4645
*
4746
* @param jsMessage The JavaScript message to be processed.
48-
* @param jsMessageCallback An optional callback to handle the result of the message processing.
4947
*/
5048
fun process(
5149
jsMessage: JsMessage,
52-
jsMessageCallback: WebViewCompatMessageCallback,
53-
onResponse: (JSONObject) -> Unit,
54-
)
50+
): ProcessResult?
5551

5652
/**
5753
* Method this handler can process.

content-scope-scripts/content-scope-scripts-impl/src/main/java/com/duckduckgo/contentscopescripts/impl/messaging/WebViewCompatWebCompatMessagingPlugin.kt

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
2828
import com.duckduckgo.di.scopes.ActivityScope
2929
import com.duckduckgo.js.messaging.api.JsCallbackData
3030
import com.duckduckgo.js.messaging.api.JsMessage
31+
import com.duckduckgo.js.messaging.api.ProcessResult.SendResponse
32+
import com.duckduckgo.js.messaging.api.ProcessResult.SendToConsumer
3133
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
3234
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
3335
import com.squareup.anvil.annotations.ContributesMultibinding
@@ -73,20 +75,30 @@ class WebViewCompatWebCompatMessagingPlugin @Inject constructor(
7375
.map { it.getGlobalJsMessageHandler() }
7476
.filter { it.method == jsMessage.method }
7577
.forEach { handler ->
76-
handler.process(jsMessage, jsMessageCallback) { }
78+
handler.process(jsMessage)?.let { processResult ->
79+
when (processResult) {
80+
is SendToConsumer -> {
81+
sendToConsumer(jsMessageCallback, jsMessage, replyProxy)
82+
}
83+
is SendResponse -> {
84+
onResponse(jsMessage, replyProxy)
85+
}
86+
}
87+
}
7788
}
7889

7990
// Process with feature handlers
8091
handlers.getPlugins().map { it.getJsMessageHandler() }.firstOrNull {
8192
it.methods.contains(jsMessage.method) && it.featureName == jsMessage.featureName
82-
}?.process(jsMessage, jsMessageCallback) { response: JSONObject ->
83-
val callbackData = JsCallbackData(
84-
id = jsMessage.id ?: "",
85-
params = response,
86-
featureName = jsMessage.featureName,
87-
method = jsMessage.method,
88-
)
89-
onResponse(callbackData, replyProxy)
93+
}?.process(jsMessage)?.let { processResult ->
94+
when (processResult) {
95+
is SendToConsumer -> {
96+
sendToConsumer(jsMessageCallback, jsMessage, replyProxy)
97+
}
98+
is SendResponse -> {
99+
onResponse(jsMessage, replyProxy)
100+
}
101+
}
90102
}
91103
}
92104
}
@@ -95,6 +107,41 @@ class WebViewCompatWebCompatMessagingPlugin @Inject constructor(
95107
}
96108
}
97109

110+
private fun onResponse(
111+
jsMessage: JsMessage,
112+
replyProxy: JavaScriptReplyProxy,
113+
) {
114+
val callbackData = JsCallbackData(
115+
id = jsMessage.id ?: "",
116+
params = jsMessage.params,
117+
featureName = jsMessage.featureName,
118+
method = jsMessage.method,
119+
)
120+
onResponse(callbackData, replyProxy)
121+
}
122+
123+
private fun sendToConsumer(
124+
jsMessageCallback: WebViewCompatMessageCallback,
125+
jsMessage: JsMessage,
126+
replyProxy: JavaScriptReplyProxy,
127+
) {
128+
jsMessageCallback.process(
129+
jsMessage.featureName,
130+
jsMessage.method,
131+
jsMessage.id ?: "",
132+
jsMessage.params,
133+
{ response: JSONObject ->
134+
val callbackData = JsCallbackData(
135+
id = jsMessage.id ?: "",
136+
params = response,
137+
featureName = jsMessage.featureName,
138+
method = jsMessage.method,
139+
)
140+
onResponse(callbackData, replyProxy)
141+
},
142+
)
143+
}
144+
98145
override fun register(
99146
jsMessageCallback: WebViewCompatMessageCallback,
100147
webView: WebView,
@@ -111,7 +158,7 @@ class WebViewCompatWebCompatMessagingPlugin @Inject constructor(
111158
process(
112159
message.data ?: "",
113160
jsMessageCallback,
114-
replyProxy
161+
replyProxy,
115162
)
116163
}
117164
}.getOrElse { exception ->

content-scope-scripts/content-scope-scripts-impl/src/test/java/com/duckduckgo/contentscopescripts/impl/messaging/WebViewCompatWebCompatMessagingPluginTest.kt

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import com.duckduckgo.common.utils.plugins.PluginPoint
2525
import com.duckduckgo.contentscopescripts.api.WebViewCompatContentScopeJsMessageHandlersPlugin
2626
import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
2727
import com.duckduckgo.js.messaging.api.JsMessage
28+
import com.duckduckgo.js.messaging.api.ProcessResult
29+
import com.duckduckgo.js.messaging.api.ProcessResult.SendToConsumer
2830
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
2931
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler
3032
import junit.framework.TestCase.assertEquals
@@ -65,16 +67,8 @@ class WebViewCompatWebCompatMessagingPluginTest {
6567
return object : WebViewCompatMessageHandler {
6668
override fun process(
6769
jsMessage: JsMessage,
68-
jsMessageCallback: WebViewCompatMessageCallback?,
69-
onResponse: (JSONObject) -> Unit,
70-
) {
71-
jsMessageCallback?.process(
72-
jsMessage.featureName,
73-
jsMessage.method,
74-
jsMessage.id,
75-
jsMessage.params,
76-
onResponse,
77-
)
70+
): ProcessResult {
71+
return SendToConsumer
7872
}
7973

8074
override val featureName: String = "webCompat"
@@ -96,16 +90,8 @@ class WebViewCompatWebCompatMessagingPluginTest {
9690

9791
override fun process(
9892
jsMessage: JsMessage,
99-
jsMessageCallback: WebViewCompatMessageCallback,
100-
onResponse: (JSONObject) -> Unit,
101-
) {
102-
jsMessageCallback.process(
103-
jsMessage.featureName,
104-
jsMessage.method,
105-
jsMessage.id,
106-
jsMessage.params,
107-
onResponse,
108-
)
93+
): ProcessResult {
94+
return SendToConsumer
10995
}
11096

11197
override val method: String = "addDebugFlag"

js-messaging/js-messaging-api/src/main/java/com/duckduckgo/js/messaging/api/WebViewCompatMessaging.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ interface WebViewCompatMessageCallback {
2828
)
2929
}
3030

31+
sealed interface ProcessResult {
32+
data object SendToConsumer : ProcessResult
33+
data class SendResponse(val response: JSONObject) : ProcessResult
34+
}
35+
3136
interface WebViewCompatMessageHandler {
3237
/**
3338
* Processes a JavaScript message received by the WebView using WebCompat APIs
@@ -40,12 +45,9 @@ interface WebViewCompatMessageHandler {
4045
* @param onResponse A callback function to send a response back to the JavaScript code.
4146
*/
4247

43-
// TODO: Simplify by removing the onResponse and callback
4448
fun process(
4549
jsMessage: JsMessage,
46-
jsMessageCallback: WebViewCompatMessageCallback?,
47-
onResponse: (JSONObject) -> Unit,
48-
)
50+
): ProcessResult?
4951

5052
/**
5153
* Name of the feature

web-compat/web-compat-impl/src/main/java/com/duckduckgo/webcompat/impl/messaging/webviewcompat/WebViewCompatWebCompatContentScopeJsMessageHandler.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,24 @@
1616

1717
package com.duckduckgo.webcompat.impl.messaging.webviewcompat
1818

19-
import com.duckduckgo.contentscopescripts.api.WebCompatContentScopeJsMessageHandlersPlugin
19+
import com.duckduckgo.contentscopescripts.api.WebViewCompatContentScopeJsMessageHandlersPlugin
2020
import com.duckduckgo.di.scopes.AppScope
2121
import com.duckduckgo.js.messaging.api.JsMessage
22-
import com.duckduckgo.js.messaging.api.WebCompatMessageHandler
23-
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
22+
import com.duckduckgo.js.messaging.api.ProcessResult
23+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler
2424
import com.squareup.anvil.annotations.ContributesMultibinding
2525
import javax.inject.Inject
26-
import org.json.JSONObject
2726

2827
@ContributesMultibinding(AppScope::class)
29-
class WebViewCompatWebCompatContentScopeJsMessageHandler @Inject constructor() : WebCompatContentScopeJsMessageHandlersPlugin {
28+
class WebViewCompatWebCompatContentScopeJsMessageHandler @Inject constructor() : WebViewCompatContentScopeJsMessageHandlersPlugin {
3029

31-
override fun getJsMessageHandler(): WebCompatMessageHandler = object : WebCompatMessageHandler {
30+
override fun getJsMessageHandler(): WebViewCompatMessageHandler = object : WebViewCompatMessageHandler {
3231

3332
override fun process(
3433
jsMessage: JsMessage,
35-
jsMessageCallback: WebViewCompatMessageCallback?,
36-
onResponse: (JSONObject) -> Unit,
37-
) {
38-
if (jsMessage.id == null) return
39-
jsMessageCallback?.process(featureName, jsMessage.method, jsMessage.id, jsMessage.params, onResponse)
34+
): ProcessResult? {
35+
if (jsMessage.id == null) return null
36+
return ProcessResult.SendToConsumer
4037
}
4138

4239
override val featureName: String = "webCompat"

0 commit comments

Comments
 (0)