Skip to content

Commit 4ac0fa6

Browse files
committed
Extract WebViewCompat test logic to another class
1 parent f935d84 commit 4ac0fa6

File tree

2 files changed

+74
-33
lines changed

2 files changed

+74
-33
lines changed

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

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ import com.duckduckgo.app.browser.webshare.WebShareChooser
181181
import com.duckduckgo.app.browser.webshare.WebViewCompatWebShareChooser
182182
import com.duckduckgo.app.browser.webview.WebContentDebugging
183183
import com.duckduckgo.app.browser.webview.WebViewBlobDownloadFeature
184-
import com.duckduckgo.app.browser.webview.WebViewCompatFeature
185-
import com.duckduckgo.app.browser.webview.WebViewCompatFeatureSettings
186184
import com.duckduckgo.app.browser.webview.safewebview.SafeWebViewFeature
187185
import com.duckduckgo.app.cta.ui.BrokenSitePromptDialogCta
188186
import com.duckduckgo.app.cta.ui.Cta
@@ -330,7 +328,7 @@ import com.duckduckgo.savedsites.api.models.SavedSitesNames
330328
import com.duckduckgo.savedsites.impl.bookmarks.BookmarksBottomSheetDialog
331329
import com.duckduckgo.savedsites.impl.bookmarks.FaviconPromptSheet
332330
import com.duckduckgo.savedsites.impl.dialogs.EditSavedSiteDialogFragment
333-
import com.duckduckgo.serp.logos.api.SerpLogoScreens.*
331+
import com.duckduckgo.serp.logos.api.SerpLogoScreens.EasterEggLogoScreen
334332
import com.duckduckgo.serp.logos.api.SerpLogos
335333
import com.duckduckgo.site.permissions.api.SitePermissionsDialogLauncher
336334
import com.duckduckgo.site.permissions.api.SitePermissionsGrantedListener
@@ -344,8 +342,6 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
344342
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
345343
import com.google.android.material.snackbar.BaseTransientBottomBar
346344
import com.google.android.material.snackbar.Snackbar
347-
import com.squareup.moshi.Moshi
348-
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
349345
import kotlinx.coroutines.CoroutineScope
350346
import kotlinx.coroutines.Job
351347
import kotlinx.coroutines.SupervisorJob
@@ -603,7 +599,7 @@ class BrowserTabFragment :
603599
lateinit var omnibarFeatureRepository: OmnibarFeatureRepository
604600

605601
@Inject
606-
lateinit var webViewCompatFeature: WebViewCompatFeature
602+
lateinit var webViewCompatTestHelper: WebViewCompatTestHelper
607603

608604
/**
609605
* We use this to monitor whether the user was seeing the in-context Email Protection signup prompt
@@ -3224,7 +3220,9 @@ class BrowserTabFragment :
32243220
onInContextEmailProtectionSignupPromptShown = { showNativeInContextEmailProtectionSignupPrompt() },
32253221
)
32263222
configureWebViewForBlobDownload(it)
3227-
configureWebViewForWebViewCompatTest(it)
3223+
lifecycleScope.launch {
3224+
webViewCompatTestHelper.configureWebViewForWebViewCompatTest(it)
3225+
}
32283226
configureWebViewForAutofill(it)
32293227
printInjector.addJsInterface(it) { viewModel.printFromWebView() }
32303228
autoconsent.addJsInterface(it, autoconsentCallback)
@@ -3347,32 +3345,6 @@ class BrowserTabFragment :
33473345
daxDialogIntroBubble.root.gone()
33483346
}
33493347

3350-
private var proxy: JavaScriptReplyProxy? = null
3351-
3352-
private val delay = "\$DELAY$"
3353-
private val postInitialPing = "\$POST_INITIAL_PING$"
3354-
private val replyToNativeMessages = "\$REPLY_TO_NATIVE_MESSAGES$"
3355-
3356-
private fun configureWebViewForWebViewCompatTest(webView: DuckDuckGoWebView) {
3357-
lifecycleScope.launch(dispatchers.main()) {
3358-
val script = withContext(dispatchers.io()) {
3359-
if (!webViewCompatFeature.self().isEnabled()) return@withContext null
3360-
3361-
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
3362-
val adapter = moshi.adapter(WebViewCompatFeatureSettings::class.java)
3363-
val webViewCompatSettings = webViewCompatFeature.self().getSettings()?.let {
3364-
adapter.fromJson(it)
3365-
}
3366-
context?.resources?.openRawResource(R.raw.webviewcompat_test_script)?.bufferedReader().use { it?.readText() }.orEmpty()
3367-
.replace(delay, webViewCompatSettings?.jsInitialPingDelay?.toString() ?: "0")
3368-
.replace(postInitialPing, webViewCompatFeature.jsSendsInitialPing().isEnabled().toString())
3369-
.replace(replyToNativeMessages, webViewCompatFeature.jsRepliesToNativeMessages().isEnabled().toString())
3370-
} ?: return@launch
3371-
3372-
webViewCompatWrapper.addDocumentStartJavaScript(webView, script, setOf("*"))
3373-
}
3374-
}
3375-
33763348
@SuppressLint("AddDocumentStartJavaScriptUsage")
33773349
private fun configureWebViewForBlobDownload(webView: DuckDuckGoWebView) {
33783350
lifecycleScope.launch(dispatchers.main()) {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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
18+
19+
import androidx.webkit.JavaScriptReplyProxy
20+
import com.duckduckgo.app.browser.webview.WebViewCompatFeature
21+
import com.duckduckgo.app.browser.webview.WebViewCompatFeatureSettings
22+
import com.duckduckgo.browser.api.webviewcompat.WebViewCompatWrapper
23+
import com.duckduckgo.common.utils.DispatcherProvider
24+
import com.duckduckgo.di.scopes.FragmentScope
25+
import com.squareup.anvil.annotations.ContributesBinding
26+
import com.squareup.moshi.Moshi
27+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
28+
import dagger.SingleInstanceIn
29+
import kotlinx.coroutines.withContext
30+
import javax.inject.Inject
31+
32+
private const val delay = "\$DELAY$"
33+
private const val postInitialPing = "\$POST_INITIAL_PING$"
34+
private const val replyToNativeMessages = "\$REPLY_TO_NATIVE_MESSAGES$"
35+
36+
interface WebViewCompatTestHelper {
37+
suspend fun configureWebViewForWebViewCompatTest(webView: DuckDuckGoWebView)
38+
}
39+
40+
@ContributesBinding(FragmentScope::class)
41+
@SingleInstanceIn(FragmentScope::class)
42+
class RealWebViewCompatTestHelper @Inject constructor(
43+
private val dispatchers: DispatcherProvider,
44+
private val webViewCompatFeature: WebViewCompatFeature,
45+
private val webViewCompatWrapper: WebViewCompatWrapper,
46+
) : WebViewCompatTestHelper {
47+
48+
private var proxy: JavaScriptReplyProxy? = null
49+
50+
override suspend fun configureWebViewForWebViewCompatTest(webView: DuckDuckGoWebView) {
51+
withContext(dispatchers.main()) {
52+
val script = withContext(dispatchers.io()) {
53+
if (!webViewCompatFeature.self().isEnabled()) return@withContext null
54+
55+
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
56+
val adapter = moshi.adapter(WebViewCompatFeatureSettings::class.java)
57+
val webViewCompatSettings = webViewCompatFeature.self().getSettings()?.let {
58+
adapter.fromJson(it)
59+
}
60+
webView.resources?.openRawResource(R.raw.webviewcompat_test_script)?.bufferedReader().use { it?.readText() }.orEmpty()
61+
.replace(delay, webViewCompatSettings?.jsInitialPingDelay?.toString() ?: "0")
62+
.replace(postInitialPing, webViewCompatFeature.jsSendsInitialPing().isEnabled().toString())
63+
.replace(replyToNativeMessages, webViewCompatFeature.jsRepliesToNativeMessages().isEnabled().toString())
64+
} ?: return@withContext
65+
66+
webViewCompatWrapper.addDocumentStartJavaScript(webView, script, setOf("*"))
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)