@@ -180,6 +180,8 @@ import com.duckduckgo.app.browser.webshare.WebShareChooser
180180import com.duckduckgo.app.browser.webshare.WebViewCompatWebShareChooser
181181import com.duckduckgo.app.browser.webview.WebContentDebugging
182182import com.duckduckgo.app.browser.webview.WebViewBlobDownloadFeature
183+ import com.duckduckgo.app.browser.webview.WebViewCompatFeature
184+ import com.duckduckgo.app.browser.webview.WebViewCompatFeatureSettings
183185import com.duckduckgo.app.browser.webview.safewebview.SafeWebViewFeature
184186import com.duckduckgo.app.cta.ui.BrokenSitePromptDialogCta
185187import com.duckduckgo.app.cta.ui.Cta
@@ -343,6 +345,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
343345import com.google.android.material.bottomsheet.BottomSheetDialogFragment
344346import com.google.android.material.snackbar.BaseTransientBottomBar
345347import com.google.android.material.snackbar.Snackbar
348+ import com.squareup.moshi.Moshi
349+ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
346350import kotlinx.coroutines.CoroutineScope
347351import kotlinx.coroutines.Job
348352import kotlinx.coroutines.SupervisorJob
@@ -596,6 +600,9 @@ class BrowserTabFragment :
596600 @Inject
597601 lateinit var webViewCompatWrapper: WebViewCompatWrapper
598602
603+ @Inject
604+ lateinit var webViewCompatFeature: WebViewCompatFeature
605+
599606 /* *
600607 * We use this to monitor whether the user was seeing the in-context Email Protection signup prompt
601608 * This is needed because the activity stack will be cleared if an external link is opened in our browser
@@ -3224,6 +3231,7 @@ class BrowserTabFragment :
32243231 onInContextEmailProtectionSignupPromptShown = { showNativeInContextEmailProtectionSignupPrompt() },
32253232 )
32263233 configureWebViewForBlobDownload(it)
3234+ configureWebViewForWebViewCompatTest(it)
32273235 configureWebViewForAutofill(it)
32283236 printInjector.addJsInterface(it) { viewModel.printFromWebView() }
32293237 autoconsent.addJsInterface(it, autoconsentCallback)
@@ -3369,6 +3377,32 @@ class BrowserTabFragment :
33693377 daxDialogIntroBubble.root.gone()
33703378 }
33713379
3380+ private var proxy: JavaScriptReplyProxy ? = null
3381+
3382+ private val delay = " \$ DELAY$"
3383+ private val postInitialPing = " \$ POST_INITIAL_PING$"
3384+ private val replyToNativeMessages = " \$ REPLY_TO_NATIVE_MESSAGES$"
3385+
3386+ private fun configureWebViewForWebViewCompatTest (webView : DuckDuckGoWebView ) {
3387+ lifecycleScope.launch(dispatchers.main()) {
3388+ val script = withContext(dispatchers.io()) {
3389+ if (! webViewCompatFeature.self().isEnabled()) return @withContext null
3390+
3391+ val moshi = Moshi .Builder ().add(KotlinJsonAdapterFactory ()).build()
3392+ val adapter = moshi.adapter(WebViewCompatFeatureSettings ::class .java)
3393+ val webViewCompatSettings = webViewCompatFeature.self().getSettings()?.let {
3394+ adapter.fromJson(it)
3395+ }
3396+ context?.resources?.openRawResource(R .raw.webviewcompat_test_script)?.bufferedReader().use { it?.readText() }.orEmpty()
3397+ .replace(delay, webViewCompatSettings?.jsInitialPingDelay?.toString() ? : " 0" )
3398+ .replace(postInitialPing, webViewCompatFeature.jsSendsInitialPing().isEnabled().toString())
3399+ .replace(replyToNativeMessages, webViewCompatFeature.jsRepliesToNativeMessages().isEnabled().toString())
3400+ } ? : return @launch
3401+
3402+ webViewCompatWrapper.addDocumentStartJavaScript(webView, script, setOf (" *" ))
3403+ }
3404+ }
3405+
33723406 @SuppressLint(" AddDocumentStartJavaScriptUsage" )
33733407 private fun configureWebViewForBlobDownload (webView : DuckDuckGoWebView ) {
33743408 lifecycleScope.launch(dispatchers.main()) {
0 commit comments