Skip to content

Commit ca097bc

Browse files
committed
Simplify message handling APIs
1 parent 668db82 commit ca097bc

File tree

8 files changed

+84
-57
lines changed

8 files changed

+84
-57
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.On
8888
import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.Unavailable
8989
import com.duckduckgo.feature.toggles.api.Toggle
9090
import com.duckduckgo.history.api.NavigationHistory
91-
import com.duckduckgo.js.messaging.api.JsMessageCallback
91+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
9292
import com.duckduckgo.privacy.config.api.AmpLinks
9393
import com.duckduckgo.subscriptions.api.Subscriptions
9494
import com.duckduckgo.user.agent.api.ClientBrandHintProvider
@@ -353,7 +353,7 @@ class BrowserWebViewClientTest {
353353
@Test
354354
fun whenConfigureWebViewThenInjectJsCode() {
355355
assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.plugin.countInitted)
356-
val mockCallback = mock<JsMessageCallback>()
356+
val mockCallback = mock<WebViewCompatMessageCallback>()
357357
testee.configureWebView(DuckDuckGoWebView(context), mockCallback)
358358
assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.plugin.countInitted)
359359
}
@@ -362,15 +362,15 @@ class BrowserWebViewClientTest {
362362
@Test
363363
fun whenConfigureWebViewThenAddWebMessageListener() {
364364
assertFalse(fakeMessagingPlugins.plugin.registered)
365-
val mockCallback = mock<JsMessageCallback>()
365+
val mockCallback = mock<WebViewCompatMessageCallback>()
366366
testee.configureWebView(DuckDuckGoWebView(context), mockCallback)
367367
assertTrue(fakeMessagingPlugins.plugin.registered)
368368
}
369369

370370
@UiThreadTest
371371
@Test
372372
fun whenDestroyThenRemoveWebMessageListener() = runTest {
373-
val mockCallback = mock<JsMessageCallback>()
373+
val mockCallback = mock<WebViewCompatMessageCallback>()
374374
val webView = DuckDuckGoWebView(context)
375375
testee.configureWebView(webView, mockCallback)
376376
assertTrue(fakeMessagingPlugins.plugin.registered)
@@ -1345,7 +1345,7 @@ class BrowserWebViewClientTest {
13451345
}
13461346

13471347
override suspend fun register(
1348-
jsMessageCallback: JsMessageCallback?,
1348+
jsMessageCallback: WebViewCompatMessageCallback?,
13491349
registerer: suspend (objectName: String, allowedOriginRules: Set<String>, webMessageListener: WebMessageListener) -> Boolean,
13501350
) {
13511351
registered = true

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.WebViewCompatMessageHandler.ProcessResult
22+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler.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.WebViewCompatMessageHandler.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: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import com.duckduckgo.di.scopes.ActivityScope
2929
import com.duckduckgo.js.messaging.api.JsCallbackData
3030
import com.duckduckgo.js.messaging.api.JsMessage
3131
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
32+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler.ProcessResult.SendResponse
33+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler.ProcessResult.SendToConsumer
3234
import com.squareup.anvil.annotations.ContributesMultibinding
3335
import com.squareup.moshi.Moshi
3436
import javax.inject.Inject
@@ -70,20 +72,30 @@ class WebViewCompatWebCompatMessagingPlugin @Inject constructor(
7072
.map { it.getGlobalJsMessageHandler() }
7173
.filter { it.method == jsMessage.method }
7274
.forEach { handler ->
73-
handler.process(jsMessage, jsMessageCallback) { }
75+
handler.process(jsMessage)?.let { processResult ->
76+
when (processResult) {
77+
is SendToConsumer -> {
78+
sendToConsumer(jsMessageCallback, jsMessage, replyProxy)
79+
}
80+
is SendResponse -> {
81+
onResponse(jsMessage, replyProxy)
82+
}
83+
}
84+
}
7485
}
7586

7687
// Process with feature handlers
7788
handlers.getPlugins().map { it.getJsMessageHandler() }.firstOrNull {
7889
it.methods.contains(jsMessage.method) && it.featureName == jsMessage.featureName
79-
}?.process(jsMessage, jsMessageCallback) { response: JSONObject ->
80-
val callbackData = JsCallbackData(
81-
id = jsMessage.id ?: "",
82-
params = response,
83-
featureName = jsMessage.featureName,
84-
method = jsMessage.method,
85-
)
86-
onResponse(callbackData, replyProxy)
90+
}?.process(jsMessage)?.let { processResult ->
91+
when (processResult) {
92+
is SendToConsumer -> {
93+
sendToConsumer(jsMessageCallback, jsMessage, replyProxy)
94+
}
95+
is SendResponse -> {
96+
onResponse(jsMessage, replyProxy)
97+
}
98+
}
8799
}
88100
}
89101
}
@@ -92,6 +104,41 @@ class WebViewCompatWebCompatMessagingPlugin @Inject constructor(
92104
}
93105
}
94106

107+
private fun onResponse(
108+
jsMessage: JsMessage,
109+
replyProxy: JavaScriptReplyProxy,
110+
) {
111+
val callbackData = JsCallbackData(
112+
id = jsMessage.id ?: "",
113+
params = jsMessage.params,
114+
featureName = jsMessage.featureName,
115+
method = jsMessage.method,
116+
)
117+
onResponse(callbackData, replyProxy)
118+
}
119+
120+
private fun sendToConsumer(
121+
jsMessageCallback: WebViewCompatMessageCallback,
122+
jsMessage: JsMessage,
123+
replyProxy: JavaScriptReplyProxy,
124+
) {
125+
jsMessageCallback.process(
126+
jsMessage.featureName,
127+
jsMessage.method,
128+
jsMessage.id ?: "",
129+
jsMessage.params,
130+
{ response: JSONObject ->
131+
val callbackData = JsCallbackData(
132+
id = jsMessage.id ?: "",
133+
params = response,
134+
featureName = jsMessage.featureName,
135+
method = jsMessage.method,
136+
)
137+
onResponse(callbackData, replyProxy)
138+
},
139+
)
140+
}
141+
95142
override suspend fun register(
96143
jsMessageCallback: WebViewCompatMessageCallback?,
97144
registerer: suspend (objectName: String, allowedOriginRules: Set<String>, webMessageListener: WebMessageListener) -> Boolean,

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,8 @@ class WebViewCompatWebCompatMessagingPluginTest {
5757
return object : WebViewCompatMessageHandler {
5858
override fun process(
5959
jsMessage: JsMessage,
60-
jsMessageCallback: WebViewCompatMessageCallback?,
61-
onResponse: (JSONObject) -> Unit,
62-
) {
63-
jsMessageCallback?.process(
64-
jsMessage.featureName,
65-
jsMessage.method,
66-
jsMessage.id,
67-
jsMessage.params,
68-
onResponse,
69-
)
60+
): WebViewCompatMessageHandler.ProcessResult {
61+
return WebViewCompatMessageHandler.ProcessResult.SendToConsumer
7062
}
7163

7264
override val featureName: String = "webCompat"

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
@@ -40,12 +40,14 @@ interface WebViewCompatMessageHandler {
4040
* @param onResponse A callback function to send a response back to the JavaScript code.
4141
*/
4242

43-
// TODO: Simplify by removing the onResponse and callback
43+
sealed interface ProcessResult {
44+
data object SendToConsumer : ProcessResult
45+
data class SendResponse(val response: JSONObject) : ProcessResult
46+
}
47+
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.WebViewCompatMessageHandler
23+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler.ProcessResult
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)