Skip to content

Commit a62a04d

Browse files
committed
Also use existing DuckDuckGoWebView methods for messages
1 parent e08973d commit a62a04d

File tree

6 files changed

+63
-17
lines changed

6 files changed

+63
-17
lines changed

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import androidx.core.view.NestedScrollingChild3
3434
import androidx.core.view.NestedScrollingChildHelper
3535
import androidx.core.view.ViewCompat
3636
import androidx.webkit.ScriptHandler
37-
import androidx.webkit.WebViewCompat
3837
import androidx.webkit.WebViewCompat.WebMessageListener
3938
import com.duckduckgo.anvil.annotations.InjectWith
4039
import com.duckduckgo.app.browser.api.DuckDuckGoWebView
@@ -437,7 +436,7 @@ class RealDuckDuckGoWebView : DuckDuckGoWebView, NestedScrollingChild3 {
437436
listener: WebMessageListener,
438437
): Boolean = runCatching {
439438
if (webViewCapabilityChecker.isSupported(WebViewCapability.WebMessageListener) && !isDestroyed) {
440-
WebViewCompat.addWebMessageListener(
439+
webViewCompatWrapper.addWebMessageListener(
441440
this,
442441
jsObjectName,
443442
allowedOriginRules,
@@ -452,6 +451,18 @@ class RealDuckDuckGoWebView : DuckDuckGoWebView, NestedScrollingChild3 {
452451
false
453452
}
454453

454+
override suspend fun safeRemoveWebMessageListener(jsObjectName: String): Boolean = runCatching {
455+
if (webViewCapabilityChecker.isSupported(WebViewCapability.WebMessageListener) && !isDestroyed) {
456+
webViewCompatWrapper.removeWebMessageListener(this, jsObjectName)
457+
true
458+
} else {
459+
false
460+
}
461+
}.getOrElse { exception ->
462+
logcat(ERROR) { "Error removing WebMessageListener: $jsObjectName: ${exception.asLog()}" }
463+
false
464+
}
465+
455466
@SuppressLint("RequiresFeature")
456467
override suspend fun safeAddDocumentStartJavaScript(
457468
script: String,

browser-api/src/main/java/com/duckduckgo/app/browser/api/DuckDuckGoWebView.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ abstract class DuckDuckGoWebView(
4646
listener: WebMessageListener,
4747
): Boolean
4848

49+
abstract suspend fun safeRemoveWebMessageListener(
50+
jsObjectName: String,
51+
): Boolean
52+
4953
abstract suspend fun safeAddDocumentStartJavaScript(
5054
script: String,
5155
allowedOriginRules: Set<String>,

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

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

1919
import android.annotation.SuppressLint
20+
import android.webkit.WebView
2021
import androidx.webkit.ScriptHandler
2122
import androidx.webkit.WebViewCompat
2223
import com.duckduckgo.di.scopes.AppScope
@@ -38,4 +39,20 @@ class RealWebViewCompatWrapper @Inject constructor() : WebViewCompatWrapper {
3839
): ScriptHandler {
3940
return WebViewCompat.addDocumentStartJavaScript(webView, script, allowedOriginRules)
4041
}
42+
43+
override fun removeWebMessageListener(webView: WebView, jsObjectName: String) {
44+
WebViewCompat.removeWebMessageListener(
45+
webView,
46+
jsObjectName,
47+
)
48+
}
49+
50+
override fun addWebMessageListener(
51+
webView: WebView,
52+
jsObjectName: String,
53+
allowedOriginRules: Set<String>,
54+
listener: WebViewCompat.WebMessageListener,
55+
) {
56+
return WebViewCompat.addWebMessageListener(webView, jsObjectName, allowedOriginRules, listener)
57+
}
4158
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.duckduckgo.contentscopescripts.impl
1818

1919
import android.webkit.WebView
2020
import androidx.webkit.ScriptHandler
21+
import androidx.webkit.WebViewCompat.WebMessageListener
2122

2223
interface WebViewCompatWrapper {
2324

@@ -26,4 +27,16 @@ interface WebViewCompatWrapper {
2627
script: String,
2728
allowedOriginRules: Set<String>,
2829
): ScriptHandler
30+
31+
fun removeWebMessageListener(
32+
webView: WebView,
33+
jsObjectName: String,
34+
)
35+
36+
fun addWebMessageListener(
37+
webView: WebView,
38+
jsObjectName: String,
39+
allowedOriginRules: Set<String>,
40+
listener: WebMessageListener,
41+
)
2942
}

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616

1717
package com.duckduckgo.contentscopescripts.impl.messaging
1818

19-
import android.annotation.SuppressLint
2019
import android.webkit.WebView
21-
import androidx.webkit.WebViewCompat
22-
import androidx.webkit.WebViewFeature
20+
import com.duckduckgo.app.browser.api.DuckDuckGoWebView
2321
import com.duckduckgo.common.utils.DispatcherProvider
2422
import com.duckduckgo.common.utils.plugins.PluginPoint
2523
import com.duckduckgo.contentscopescripts.api.AdsjsContentScopeJsMessageHandlersPlugin
@@ -85,16 +83,14 @@ class AdsjsContentScopeMessaging @Inject constructor(
8583
}
8684
}
8785

88-
@SuppressLint("AddWebMessageListenerUsage")
8986
override suspend fun register(webView: WebView, jsMessageCallback: JsMessageCallback?) {
9087
if (withContext(dispatcherProvider.io()) { !adsJsContentScopeScripts.isEnabled() }) return
9188
if (jsMessageCallback == null) throw Exception("Callback cannot be null")
9289
this.webView = webView
9390

9491
runCatching {
95-
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
96-
WebViewCompat.addWebMessageListener(
97-
webView,
92+
(webView as? DuckDuckGoWebView)?.let {
93+
return@runCatching it.safeAddWebMessageListener(
9894
JS_OBJECT_NAME,
9995
allowedDomains,
10096
) { _, message, _, _, replyProxy ->
@@ -103,10 +99,7 @@ class AdsjsContentScopeMessaging @Inject constructor(
10399
jsMessageCallback,
104100
)
105101
}
106-
true
107-
} else {
108-
false
109-
}
102+
} ?: false
110103
}.getOrElse { exception ->
111104
logcat(ERROR) { "Error adding WebMessageListener for contentScopeAdsjs: ${exception.asLog()}" }
112105
false
@@ -117,10 +110,11 @@ class AdsjsContentScopeMessaging @Inject constructor(
117110
if (!adsJsContentScopeScripts.isEnabled()) return
118111
withContext(dispatcherProvider.main()) {
119112
runCatching {
120-
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
121-
WebViewCompat.removeWebMessageListener(webView, JS_OBJECT_NAME)
122-
} else {
123-
logcat(ERROR) { "WebMessageListener is not supported on this WebView" }
113+
return@runCatching (webView as? DuckDuckGoWebView)
114+
?.safeRemoveWebMessageListener(JS_OBJECT_NAME)
115+
}.getOrElse { exception ->
116+
logcat(ERROR) {
117+
"Error removing WebMessageListener for contentScopeAdsjs: ${exception.asLog()}"
124118
}
125119
}
126120
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package com.duckduckgo.contentscopescripts.impl
1919
import android.annotation.SuppressLint
2020
import com.duckduckgo.app.privacy.db.UserAllowListRepository
2121
import com.duckduckgo.appbuildconfig.api.AppBuildConfig
22+
import com.duckduckgo.common.test.CoroutineTestRule
2223
import com.duckduckgo.common.utils.plugins.PluginPoint
2324
import com.duckduckgo.contentscopescripts.api.ContentScopeConfigPlugin
2425
import com.duckduckgo.feature.toggles.api.FakeFeatureToggleFactory
@@ -33,6 +34,7 @@ import junit.framework.TestCase.assertFalse
3334
import junit.framework.TestCase.assertTrue
3435
import kotlinx.coroutines.test.runTest
3536
import org.junit.Before
37+
import org.junit.Rule
3638
import org.junit.Test
3739
import org.mockito.kotlin.mock
3840
import org.mockito.kotlin.times
@@ -42,6 +44,10 @@ import org.mockito.kotlin.whenever
4244
@SuppressLint("DenyListedApi")
4345
class RealAdsjsContentScopeScriptsTest {
4446

47+
@get:Rule
48+
@Suppress("unused")
49+
val coroutineRule = CoroutineTestRule()
50+
4551
private val mockPluginPoint: PluginPoint<ContentScopeConfigPlugin> = mock()
4652
private val mockUserAllowListRepository: UserAllowListRepository = mock()
4753
private val mockContentScopeJsReader: ContentScopeJSReader = mock()
@@ -64,6 +70,7 @@ class RealAdsjsContentScopeScriptsTest {
6470
mockUnprotectedTemporary,
6571
mockFingerprintProtectionManager,
6672
contentScopeScriptsFeature,
73+
coroutineRule.testDispatcherProvider,
6774
)
6875
whenever(mockPlugin1.config()).thenReturn(config1)
6976
whenever(mockPlugin2.config()).thenReturn(config2)

0 commit comments

Comments
 (0)