Skip to content

Commit 0222457

Browse files
committed
Add plugins at the browser level
1 parent c64cbba commit 0222457

File tree

12 files changed

+108
-49
lines changed

12 files changed

+108
-49
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
@@ -87,7 +87,7 @@ import com.duckduckgo.history.api.NavigationHistory
8787
import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScript
8888
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
8989
import com.duckduckgo.js.messaging.api.SubscriptionEventData
90-
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
90+
import com.duckduckgo.js.messaging.api.WebMessaging
9191
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
9292
import com.duckduckgo.privacy.config.api.AmpLinks
9393
import com.duckduckgo.subscriptions.api.Subscriptions
@@ -1349,7 +1349,7 @@ class BrowserWebViewClientTest {
13491349
override fun getPlugins() = listOf(plugin)
13501350
}
13511351

1352-
class FakeWebMessagingPlugin : WebMessagingPlugin {
1352+
class FakeWebMessagingPlugin : WebMessaging {
13531353
var registered = false
13541354
private set
13551355

@@ -1371,10 +1371,10 @@ class BrowserWebViewClientTest {
13711371
get() = "test"
13721372
}
13731373

1374-
class FakeWebMessagingPluginPoint : PluginPoint<WebMessagingPlugin> {
1374+
class FakeWebMessagingPluginPoint : PluginPoint<WebMessaging> {
13751375
val plugin = FakeWebMessagingPlugin()
13761376

1377-
override fun getPlugins(): Collection<WebMessagingPlugin> {
1377+
override fun getPlugins(): Collection<WebMessaging> {
13781378
return listOf(plugin)
13791379
}
13801380
}

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/ContentScopeScriptsAddDocumentStartJavaScriptTest.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.duckduckgo.app.browser.api.WebViewCapabilityChecker
55
import com.duckduckgo.browser.api.webviewcompat.WebViewCompatWrapper
66
import com.duckduckgo.common.test.CoroutineTestRule
77
import com.duckduckgo.contentscopescripts.api.contentscopeExperiments.ContentScopeExperiments
8+
import com.duckduckgo.js.messaging.api.AddDocumentStartScriptDelegate
89
import kotlinx.coroutines.test.runTest
910
import org.junit.Before
1011
import org.junit.Rule
@@ -25,6 +26,7 @@ class ContentScopeScriptsAddDocumentStartJavaScriptTest {
2526
private val mockWebViewCompatWrapper: WebViewCompatWrapper = mock()
2627
private val mockWebView: WebView = mock()
2728
private val mockActiveContentScopeExperiments: ContentScopeExperiments = mock()
29+
private val mockScriptInjectorDelegate: AddDocumentStartScriptDelegate = mock()
2830

2931
private lateinit var testee: ContentScopeScriptsAddDocumentStartJavaScript
3032

@@ -33,11 +35,8 @@ class ContentScopeScriptsAddDocumentStartJavaScriptTest {
3335
whenever(mockActiveContentScopeExperiments.getActiveExperiments()).thenReturn(listOf())
3436
testee = ContentScopeScriptsAddDocumentStartJavaScript(
3537
mockWebViewCompatContentScopeScripts,
36-
coroutineRule.testDispatcherProvider,
37-
mockWebViewCapabilityChecker,
38-
mockWebViewCompatWrapper,
3938
mockActiveContentScopeExperiments,
40-
coroutineRule.testScope,
39+
mockScriptInjectorDelegate,
4140
)
4241
}
4342

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,

0 commit comments

Comments
 (0)