Skip to content

Commit e385b16

Browse files
committed
Add plugins at the browser level
1 parent 567e489 commit e385b16

File tree

11 files changed

+105
-45
lines changed

11 files changed

+105
-45
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ import com.duckduckgo.history.api.NavigationHistory
8888
import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScript
8989
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
9090
import com.duckduckgo.js.messaging.api.SubscriptionEventData
91-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
91+
import com.duckduckgo.js.messaging.api.WebMessaging
9292
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
9393
import com.duckduckgo.privacy.config.api.AmpLinks
9494
import com.duckduckgo.subscriptions.api.Subscriptions
@@ -1358,7 +1358,7 @@ class BrowserWebViewClientTest {
13581358
override fun getPlugins() = listOf(plugin)
13591359
}
13601360

1361-
class FakeWebMessagingPlugin : WebMessagingPlugin {
1361+
class FakeWebMessagingPlugin : WebMessaging {
13621362
var registered = false
13631363
private set
13641364

@@ -1380,10 +1380,10 @@ class BrowserWebViewClientTest {
13801380
get() = "test"
13811381
}
13821382

1383-
class FakeWebMessagingPluginPoint : PluginPoint<WebMessagingPlugin> {
1383+
class FakeWebMessagingPluginPoint : PluginPoint<WebMessaging> {
13841384
val plugin = FakeWebMessagingPlugin()
13851385

1386-
override fun getPlugins(): Collection<WebMessagingPlugin> {
1386+
override fun getPlugins(): Collection<WebMessaging> {
13871387
return listOf(plugin)
13881388
}
13891389
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import com.duckduckgo.autofill.api.BrowserAutofill
6767
import com.duckduckgo.autofill.api.InternalTestUserChecker
6868
import com.duckduckgo.browser.api.AddDocumentStartJavaScriptPlugin
6969
import com.duckduckgo.browser.api.JsInjectorPlugin
70+
import com.duckduckgo.browser.api.WebMessagingBrowserPlugin
7071
import com.duckduckgo.common.utils.AppUrl.ParamKey.QUERY
7172
import com.duckduckgo.common.utils.CurrentTimeProvider
7273
import com.duckduckgo.common.utils.DispatcherProvider
@@ -82,7 +83,6 @@ import com.duckduckgo.duckplayer.impl.DUCK_PLAYER_OPEN_IN_YOUTUBE_PATH
8283
import com.duckduckgo.history.api.NavigationHistory
8384
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
8485
import com.duckduckgo.js.messaging.api.SubscriptionEventData
85-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
8686
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
8787
import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed
8888
import com.duckduckgo.privacy.config.api.AmpLinks
@@ -132,7 +132,7 @@ class BrowserWebViewClient @Inject constructor(
132132
private val duckChat: DuckChat,
133133
private val contentScopeExperiments: ContentScopeExperiments,
134134
private val addDocumentStartJavascriptPlugins: PluginPoint<AddDocumentStartJavaScriptPlugin>,
135-
private val webMessagingPlugins: PluginPoint<WebMessagingPlugin>,
135+
private val webMessagingPlugins: PluginPoint<WebMessagingBrowserPlugin>,
136136
private val postMessageWrapperPlugins: PluginPoint<PostMessageWrapperPlugin>,
137137
) : WebViewClient() {
138138

@@ -478,7 +478,7 @@ class BrowserWebViewClient @Inject constructor(
478478

479479
callback?.let {
480480
webMessagingPlugins.getPlugins().forEach { plugin ->
481-
plugin.register(callback, webView)
481+
plugin.webMessaging().register(callback, webView)
482482
}
483483
}
484484
}
@@ -763,7 +763,7 @@ class BrowserWebViewClient @Inject constructor(
763763

764764
fun destroy(webView: DuckDuckGoWebView) {
765765
webMessagingPlugins.getPlugins().forEach { plugin ->
766-
plugin.unregister(webView)
766+
plugin.webMessaging().unregister(webView)
767767
}
768768
}
769769

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.browser.messaging
18+
19+
import com.duckduckgo.browser.api.WebMessagingBrowserPlugin
20+
import com.duckduckgo.contentscopescripts.impl.messaging.ContentScopeScriptsWebMessaging
21+
import com.duckduckgo.di.scopes.FragmentScope
22+
import com.duckduckgo.js.messaging.api.WebMessaging
23+
import com.squareup.anvil.annotations.ContributesBinding
24+
import com.squareup.anvil.annotations.ContributesMultibinding
25+
import dagger.SingleInstanceIn
26+
import javax.inject.Inject
27+
import javax.inject.Named
28+
29+
@Named("contentScopeScripts")
30+
@SingleInstanceIn(FragmentScope::class)
31+
@ContributesBinding(FragmentScope::class)
32+
@ContributesMultibinding(scope = FragmentScope::class, ignoreQualifier = true)
33+
class ContentScopeScriptsWebMessagingBrowserPlugin @Inject constructor(
34+
private val contentScopeScriptsWebMessaging: ContentScopeScriptsWebMessaging,
35+
) : WebMessagingBrowserPlugin {
36+
override fun webMessaging(): WebMessaging {
37+
return contentScopeScriptsWebMessaging
38+
}
39+
}

app/src/main/java/com/duckduckgo/app/plugins/WebMessagingPluginPoint.kt renamed to app/src/main/java/com/duckduckgo/app/plugins/WebMessagingBrowserPluginPoint.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
package com.duckduckgo.app.plugins
1818

1919
import com.duckduckgo.anvil.annotations.ContributesPluginPoint
20+
import com.duckduckgo.browser.api.WebMessagingBrowserPlugin
2021
import com.duckduckgo.di.scopes.AppScope
21-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
2222

2323
@ContributesPluginPoint(
2424
scope = AppScope::class,
25-
boundType = WebMessagingPlugin::class,
25+
boundType = WebMessagingBrowserPlugin::class,
2626
)
2727
@Suppress("unused")
28-
interface UnusedWebMessagingPluginPoint
28+
interface UnusedWebMessagingBrowserPluginPoint
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.browser.api
18+
19+
import com.duckduckgo.js.messaging.api.WebMessaging
20+
21+
interface WebMessagingBrowserPlugin {
22+
fun webMessaging(): WebMessaging
23+
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import com.duckduckgo.js.messaging.api.JsMessageHelper
2626
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
2727
import com.duckduckgo.js.messaging.api.SubscriptionEvent
2828
import com.duckduckgo.js.messaging.api.SubscriptionEventData
29-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
29+
import com.duckduckgo.js.messaging.api.WebMessaging
3030
import com.squareup.anvil.annotations.ContributesMultibinding
3131
import javax.inject.Inject
3232
import javax.inject.Named
@@ -35,7 +35,7 @@ import kotlinx.coroutines.launch
3535

3636
@ContributesMultibinding(FragmentScope::class)
3737
class ContentScopeScriptsPostMessageWrapperPlugin @Inject constructor(
38-
@Named("contentScopeScripts") private val webMessagingPlugin: WebMessagingPlugin,
38+
@Named("contentScopeScripts") private val webMessaging: WebMessaging,
3939
private val jsMessageHelper: JsMessageHelper,
4040
private val coreContentScopeScripts: CoreContentScopeScripts,
4141
private val webViewCompatContentScopeScripts: WebViewCompatContentScopeScripts,
@@ -45,11 +45,11 @@ class ContentScopeScriptsPostMessageWrapperPlugin @Inject constructor(
4545
override fun postMessage(message: SubscriptionEventData, webView: WebView) {
4646
coroutineScope.launch {
4747
if (webViewCompatContentScopeScripts.isEnabled()) {
48-
webMessagingPlugin.postMessage(message)
48+
webMessaging.postMessage(message)
4949
} else {
5050
jsMessageHelper.sendSubscriptionEvent(
5151
subscriptionEvent = SubscriptionEvent(
52-
context = webMessagingPlugin.context,
52+
context = webMessaging.context,
5353
featureName = message.featureName,
5454
subscriptionName = message.subscriptionName,
5555
params = message.params,
@@ -63,5 +63,5 @@ class ContentScopeScriptsPostMessageWrapperPlugin @Inject constructor(
6363
}
6464

6565
override val context: String
66-
get() = webMessagingPlugin.context
66+
get() = webMessaging.context
6767
}
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,25 @@ import com.duckduckgo.contentscopescripts.api.WebViewCompatContentScopeJsMessage
2121
import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
2222
import com.duckduckgo.di.scopes.FragmentScope
2323
import com.duckduckgo.js.messaging.api.GlobalJsMessageHandler
24-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
25-
import com.duckduckgo.js.messaging.api.WebMessagingPluginDelegate
26-
import com.duckduckgo.js.messaging.api.WebMessagingPluginStrategy
24+
import com.duckduckgo.js.messaging.api.WebMessaging
25+
import com.duckduckgo.js.messaging.api.WebMessagingDelegate
26+
import com.duckduckgo.js.messaging.api.WebMessagingStrategy
2727
import com.duckduckgo.js.messaging.api.WebViewCompatMessageHandler
2828
import com.squareup.anvil.annotations.ContributesBinding
29-
import com.squareup.anvil.annotations.ContributesMultibinding
3029
import dagger.SingleInstanceIn
3130
import javax.inject.Inject
3231
import javax.inject.Named
3332

3433
@Named("contentScopeScripts")
3534
@SingleInstanceIn(FragmentScope::class)
3635
@ContributesBinding(FragmentScope::class)
37-
@ContributesMultibinding(scope = FragmentScope::class, ignoreQualifier = true)
38-
class ContentScopeScriptsWebMessagingPlugin @Inject constructor(
36+
class ContentScopeScriptsWebMessaging @Inject constructor(
3937
handlers: PluginPoint<WebViewCompatContentScopeJsMessageHandlersPlugin>,
4038
globalHandlers: PluginPoint<GlobalContentScopeJsMessageHandlersPlugin>,
4139
webViewCompatContentScopeScripts: WebViewCompatContentScopeScripts,
42-
webMessagingPluginDelegate: WebMessagingPluginDelegate,
43-
) : WebMessagingPlugin by webMessagingPluginDelegate.createPlugin(
44-
object : WebMessagingPluginStrategy {
40+
webMessagingDelegate: WebMessagingDelegate,
41+
) : WebMessaging by webMessagingDelegate.createPlugin(
42+
object : WebMessagingStrategy {
4543
override val context: String = "contentScopeScripts"
4644
override val allowedDomains: Set<String> = setOf("*")
4745
override val objectName: String

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
77
import com.duckduckgo.js.messaging.api.JsMessageHelper
88
import com.duckduckgo.js.messaging.api.SubscriptionEvent
99
import com.duckduckgo.js.messaging.api.SubscriptionEventData
10-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
10+
import com.duckduckgo.js.messaging.api.WebMessaging
1111
import kotlinx.coroutines.test.runTest
1212
import org.json.JSONObject
1313
import org.junit.Before
@@ -23,7 +23,7 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
2323
@get:Rule
2424
var coroutineRule = CoroutineTestRule()
2525

26-
private val mockWebMessagingPlugin: WebMessagingPlugin = mock()
26+
private val mockWebMessaging: WebMessaging = mock()
2727
private val mockJsHelper: JsMessageHelper = mock()
2828
private val mockCoreContentScopeScripts: CoreContentScopeScripts = mock()
2929
private val mockWebViewCompatContentScopeScripts: WebViewCompatContentScopeScripts = mock()
@@ -42,7 +42,7 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
4242
)
4343

4444
val testee = ContentScopeScriptsPostMessageWrapperPlugin(
45-
webMessagingPlugin = mockWebMessagingPlugin,
45+
webMessaging = mockWebMessaging,
4646
jsMessageHelper = mockJsHelper,
4747
coreContentScopeScripts = mockCoreContentScopeScripts,
4848
webViewCompatContentScopeScripts = mockWebViewCompatContentScopeScripts,
@@ -53,7 +53,7 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
5353
fun setup() {
5454
whenever(mockCoreContentScopeScripts.callbackName).thenReturn("callbackName")
5555
whenever(mockCoreContentScopeScripts.secret).thenReturn("secret")
56-
whenever(mockWebMessagingPlugin.context).thenReturn("contentScopeScripts")
56+
whenever(mockWebMessaging.context).thenReturn("contentScopeScripts")
5757
whenever(mockJsonObject.toString()).thenReturn("{}")
5858
}
5959

@@ -63,7 +63,7 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
6363

6464
testee.postMessage(subscriptionEventData, mockWebView)
6565

66-
verify(mockWebMessagingPlugin).postMessage(subscriptionEventData)
66+
verify(mockWebMessaging).postMessage(subscriptionEventData)
6767
}
6868

6969
@Test
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import org.mockito.kotlin.verify
4646
import org.mockito.kotlin.whenever
4747

4848
@RunWith(AndroidJUnit4::class)
49-
class ContentScopeScriptsWebMessagingPluginTest {
49+
class ContentScopeScriptsWebMessagingTest {
5050

5151
@get:Rule
5252
val coroutineRule = CoroutineTestRule()
@@ -57,7 +57,7 @@ class ContentScopeScriptsWebMessagingPluginTest {
5757
private val globalHandlers: PluginPoint<GlobalContentScopeJsMessageHandlersPlugin> = FakeGlobalHandlersPluginPoint()
5858
private val mockWebViewCompatWrapper: WebViewCompatWrapper = mock()
5959
private val mockWebView: WebView = mock()
60-
private lateinit var testee: ContentScopeScriptsWebMessagingPlugin
60+
private lateinit var testee: ContentScopeScriptsWebMessaging
6161

6262
private class FakePluginPoint : PluginPoint<WebViewCompatContentScopeJsMessageHandlersPlugin> {
6363
override fun getPlugins(): Collection<WebViewCompatContentScopeJsMessageHandlersPlugin> {
@@ -105,7 +105,7 @@ class ContentScopeScriptsWebMessagingPluginTest {
105105
@Before
106106
fun setUp() = runTest {
107107
whenever(webViewCompatContentScopeScripts.isEnabled()).thenReturn(true)
108-
testee = ContentScopeScriptsWebMessagingPlugin(
108+
testee = ContentScopeScriptsWebMessaging(
109109
handlers = handlers,
110110
globalHandlers = globalHandlers,
111111
webViewCompatContentScopeScripts = webViewCompatContentScopeScripts,
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.duckduckgo.js.messaging.api
1818

1919
import android.webkit.WebView
2020

21-
interface WebMessagingPlugin {
21+
interface WebMessaging {
2222
fun register(
2323
jsMessageCallback: WebViewCompatMessageCallback,
2424
webView: WebView,
@@ -33,21 +33,21 @@ interface WebMessagingPlugin {
3333
val context: String
3434
}
3535

36-
interface WebMessagingPluginDelegate {
36+
interface WebMessagingDelegate {
3737

3838
/**
39-
* Creates a [WebMessagingPlugin] implementation with the given [WebMessagingPluginStrategy].
39+
* Creates a [WebMessaging] implementation with the given [WebMessagingStrategy].
4040
* @param strategy the strategy to use for web messaging behavior
41-
* @return [WebMessagingPlugin] implementation
41+
* @return [WebMessaging] implementation
4242
*/
43-
fun createPlugin(strategy: WebMessagingPluginStrategy): WebMessagingPlugin
43+
fun createPlugin(strategy: WebMessagingStrategy): WebMessaging
4444
}
4545

4646
/**
4747
* Strategy interface for web messaging logic.
4848
* Allows different implementations to provide their own behavior.
4949
*/
50-
interface WebMessagingPluginStrategy {
50+
interface WebMessagingStrategy {
5151
val context: String
5252
val allowedDomains: Set<String>
5353
val objectName: String

0 commit comments

Comments
 (0)