Skip to content

Commit 9acf98b

Browse files
committed
Configure script based on remote config
1 parent 5a08c8b commit 9acf98b

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ 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
184186
import com.duckduckgo.app.browser.webview.safewebview.SafeWebViewFeature
185187
import com.duckduckgo.app.cta.ui.BrokenSitePromptDialogCta
186188
import com.duckduckgo.app.cta.ui.Cta
@@ -307,6 +309,7 @@ import com.duckduckgo.js.messaging.api.JsCallbackData
307309
import com.duckduckgo.js.messaging.api.JsMessageCallback
308310
import com.duckduckgo.js.messaging.api.JsMessaging
309311
import com.duckduckgo.js.messaging.api.SubscriptionEventData
312+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
310313
import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed
311314
import com.duckduckgo.mobile.android.app.tracking.ui.AppTrackingProtectionScreens.AppTrackerOnboardingActivityWithEmptyParamsParams
312315
import com.duckduckgo.navigation.api.GlobalActivityStarter
@@ -342,6 +345,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
342345
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
343346
import com.google.android.material.snackbar.BaseTransientBottomBar
344347
import com.google.android.material.snackbar.Snackbar
348+
import com.squareup.moshi.Moshi
349+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
345350
import kotlinx.coroutines.CoroutineScope
346351
import kotlinx.coroutines.Job
347352
import kotlinx.coroutines.SupervisorJob
@@ -598,6 +603,9 @@ class BrowserTabFragment :
598603
@Inject
599604
lateinit var omnibarFeatureRepository: OmnibarFeatureRepository
600605

606+
@Inject
607+
lateinit var webViewCompatFeature: WebViewCompatFeature
608+
601609
/**
602610
* We use this to monitor whether the user was seeing the in-context Email Protection signup prompt
603611
* This is needed because the activity stack will be cleared if an external link is opened in our browser
@@ -3217,6 +3225,7 @@ class BrowserTabFragment :
32173225
onInContextEmailProtectionSignupPromptShown = { showNativeInContextEmailProtectionSignupPrompt() },
32183226
)
32193227
configureWebViewForBlobDownload(it)
3228+
configureWebViewForWebViewCompatTest(it)
32203229
configureWebViewForAutofill(it)
32213230
printInjector.addJsInterface(it) { viewModel.printFromWebView() }
32223231
autoconsent.addJsInterface(it, autoconsentCallback)
@@ -3339,6 +3348,32 @@ class BrowserTabFragment :
33393348
daxDialogIntroBubble.root.gone()
33403349
}
33413350

3351+
private var proxy: JavaScriptReplyProxy? = null
3352+
3353+
private val delay = "\$DELAY$"
3354+
private val postInitialPing = "\$POST_INITIAL_PING$"
3355+
private val replyToNativeMessages = "\$REPLY_TO_NATIVE_MESSAGES$"
3356+
3357+
private fun configureWebViewForWebViewCompatTest(webView: DuckDuckGoWebView) {
3358+
lifecycleScope.launch(dispatchers.main()) {
3359+
val script = withContext(dispatchers.io()) {
3360+
if (!webViewCompatFeature.self().isEnabled()) return@withContext null
3361+
3362+
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
3363+
val adapter = moshi.adapter(WebViewCompatFeatureSettings::class.java)
3364+
val webViewCompatSettings = webViewCompatFeature.self().getSettings()?.let {
3365+
adapter.fromJson(it)
3366+
}
3367+
context?.resources?.openRawResource(R.raw.webviewcompat_test_script)?.bufferedReader().use { it?.readText() }.orEmpty()
3368+
.replace(delay, webViewCompatSettings?.jsInitialPingDelay?.toString() ?: "0")
3369+
.replace(postInitialPing, webViewCompatFeature.jsSendsInitialPing().isEnabled().toString())
3370+
.replace(replyToNativeMessages, webViewCompatFeature.jsRepliesToNativeMessages().isEnabled().toString())
3371+
} ?: return@launch
3372+
3373+
webViewCompatWrapper.addDocumentStartJavaScript(webView, script, setOf("*"))
3374+
}
3375+
}
3376+
33423377
@SuppressLint("AddDocumentStartJavaScriptUsage")
33433378
private fun configureWebViewForBlobDownload(webView: DuckDuckGoWebView) {
33443379
lifecycleScope.launch(dispatchers.main()) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2024 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.webview
18+
19+
import com.duckduckgo.anvil.annotations.ContributesRemoteFeature
20+
import com.duckduckgo.di.scopes.AppScope
21+
import com.duckduckgo.feature.toggles.api.Toggle
22+
import com.duckduckgo.feature.toggles.api.Toggle.DefaultFeatureValue
23+
24+
@ContributesRemoteFeature(
25+
scope = AppScope::class,
26+
featureName = "webViewCompat",
27+
)
28+
interface WebViewCompatFeature {
29+
30+
@Toggle.DefaultValue(DefaultFeatureValue.FALSE)
31+
fun self(): Toggle
32+
33+
@Toggle.DefaultValue(DefaultFeatureValue.FALSE)
34+
fun jsSendsInitialPing(): Toggle
35+
36+
@Toggle.DefaultValue(DefaultFeatureValue.FALSE)
37+
fun jsRepliesToNativeMessages(): Toggle
38+
}
39+
40+
data class WebViewCompatFeatureSettings(
41+
val jsInitialPingDelay: Long = 0,
42+
)

0 commit comments

Comments
 (0)