diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt index 8589e670d73f..01ae8429624e 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt @@ -41,7 +41,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import androidx.room.Room -import androidx.test.annotation.UiThreadTest import androidx.test.filters.SdkSuppress import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.duckduckgo.adclick.api.AdClickManager @@ -617,10 +616,6 @@ class BrowserTabViewModelTest { private val mockWebView: WebView = mock() - private val fakeAddDocumentStartJavaScriptPlugins = FakeAddDocumentStartJavaScriptPluginPoint() - private val fakeMessagingPlugins = FakeWebMessagingPluginPoint() - private val fakePostMessageWrapperPlugins = FakePostMessageWrapperPluginPoint() - private val mockDeviceAppLookup: DeviceAppLookup = mock() @Before @@ -850,9 +845,6 @@ class BrowserTabViewModelTest { externalIntentProcessingState = mockExternalIntentProcessingState, vpnMenuStateProvider = mockVpnMenuStateProvider, webViewCompatWrapper = mockWebViewCompatWrapper, - addDocumentStartJavascriptPlugins = fakeAddDocumentStartJavaScriptPlugins, - webMessagingPlugins = fakeMessagingPlugins, - postMessageWrapperPlugins = fakePostMessageWrapperPlugins, addressBarTrackersAnimationFeatureToggle = mockAddressBarTrackersAnimationFeatureToggle, autoconsentPixelManager = mockAutoconsentPixelManager, ) @@ -7091,102 +7083,6 @@ class BrowserTabViewModelTest { verify(mockOnboardingDesignExperimentManager).onWebPageFinishedLoading(url) } - @Test - fun whenPageFinishedAndUpdateScriptOnPageFinishedEnabledThenAddDocumentStartJavaScript() = - runTest { - val url = "https://example.com" - val webViewNavState = WebViewNavigationState(mockStack, 100) - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(true)) - - testee.pageFinished(mockWebView, webViewNavState, url) - - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - - @Test - fun whenPageFinishedAndUpdateScriptOnPageFinishedDisabledThenDoNotCallAddDocumentStartJavaScript() = - runTest { - val url = "https://example.com" - val webViewNavState = WebViewNavigationState(mockStack, 100) - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(false)) - - testee.pageFinished(mockWebView, webViewNavState, url) - - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnPageFinishedEnabledAndUpdateScriptOnProtectionsChangedEnabledThenAddDocumentStartJavaScript() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(true)) - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(true)) - - testee.privacyProtectionsUpdated(mockWebView) - - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnProtectionsChangedEnabledAndStopLoadingBeforeUpdatingScriptEnabledThenStopLoading() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(true)) - fakeAndroidConfigBrowserFeature.stopLoadingBeforeUpdatingScript().setRawStoredState(State(true)) - - testee.privacyProtectionsUpdated(mockWebView) - - verify(mockWebView).stopLoading() - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnProtectionsChangedEnabledAndStopLoadingBeforeUpdatingScriptDisabledThenDoNotStopLoading() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(true)) - fakeAndroidConfigBrowserFeature.stopLoadingBeforeUpdatingScript().setRawStoredState(State(false)) - - testee.privacyProtectionsUpdated(mockWebView) - - verify(mockWebView, never()).stopLoading() - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnPageFinishedTrueAndUpdateScriptOnProtectionsChangedFalseThenNotAddDocumentStartJavaScript() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(true)) - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(false)) - - testee.privacyProtectionsUpdated(mockWebView) - - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnPageFinishedDisabledThenAddDocumentStartJavaScriptOnlyOnCSS() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(false)) - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(true)) - - testee.privacyProtectionsUpdated(mockWebView) - - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - - @Test - fun whenPrivacyProtectionsUpdatedAndUpdateScriptOnPageFinishedFalseAndUpdateScriptOnProtectionsChangedFalseThenNotAddDocumentStartJavaScript() = - runTest { - fakeAndroidConfigBrowserFeature.updateScriptOnPageFinished().setRawStoredState(State(false)) - fakeAndroidConfigBrowserFeature.updateScriptOnProtectionsChanged().setRawStoredState(State(false)) - - testee.privacyProtectionsUpdated(mockWebView) - - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.otherPlugin.countInitted) - } - @Test fun whenCtaShownThenFireInContextDialogShownPixel() = runTest { @@ -7689,46 +7585,6 @@ class BrowserTabViewModelTest { assertNull("SERP logo should be cleared when navigating to non-DuckDuckGo URL", omnibarViewState().serpLogo) } - @UiThreadTest - @Test - fun whenConfigureWebViewThenCallAddDocumentStartJavaScript() = - runTest { - val mockCallback = mock() - val webView = DuckDuckGoWebView(context) - assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - - testee.configureWebView(webView, mockCallback) - - assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.cssPlugin.countInitted) - } - - @UiThreadTest - @Test - fun whenConfigureWebViewThenCallAddMessageListener() = - runTest { - val mockCallback = mock() - val webView = DuckDuckGoWebView(context) - assertFalse(fakeMessagingPlugins.plugin.registered) - - testee.configureWebView(webView, mockCallback) - - assertTrue(fakeMessagingPlugins.plugin.registered) - } - - @UiThreadTest - @Test - fun whenPostMessageThenCallPostContentScopeMessage() = - runTest { - val data = SubscriptionEventData("feature", "method", JSONObject()) - val webView = DuckDuckGoWebView(context) - - assertFalse(fakePostMessageWrapperPlugins.plugin.postMessageCalled) - - testee.postContentScopeMessage(data, webView) - - assertTrue(fakePostMessageWrapperPlugins.plugin.postMessageCalled) - } - private fun aCredential(): LoginCredentials = LoginCredentials(domain = null, username = null, password = null) private fun assertShowHistoryCommandSent(expectedStackSize: Int) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 28a86a610195..c7cbd57fe90a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -307,7 +307,6 @@ import com.duckduckgo.js.messaging.api.JsCallbackData import com.duckduckgo.js.messaging.api.JsMessageCallback import com.duckduckgo.js.messaging.api.JsMessaging import com.duckduckgo.js.messaging.api.SubscriptionEventData -import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed import com.duckduckgo.mobile.android.app.tracking.ui.AppTrackingProtectionScreens.AppTrackerOnboardingActivityWithEmptyParamsParams import com.duckduckgo.navigation.api.GlobalActivityStarter @@ -1226,18 +1225,11 @@ class BrowserTabFragment : private fun onOmnibarCustomTabPrivacyDashboardPressed() { val params = PrivacyDashboardPrimaryScreen(tabId) val intent = globalActivityStarter.startIntent(requireContext(), params) - postBreakageReportingEvent() + contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData()) intent?.let { activityResultPrivacyDashboard.launch(intent) } pixel.fire(CustomTabPixelNames.CUSTOM_TABS_PRIVACY_DASHBOARD_OPENED) } - private fun postBreakageReportingEvent() { - val eventData = createBreakageReportingEventData() - webView?.let { - viewModel.postContentScopeMessage(eventData, it) - } - } - private fun onFireButtonPressed() { val isFocusedNtp = omnibar.viewMode == ViewMode.NewTab && omnibar.getText().isEmpty() && omnibar.omnibarTextInput.hasFocus() browserActivity?.launchFire(launchedFromFocusedNtp = isFocusedNtp) @@ -1245,12 +1237,12 @@ class BrowserTabFragment : } private fun onBrowserMenuButtonPressed() { - postBreakageReportingEvent() + contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData()) viewModel.onBrowserMenuClicked(isCustomTab = isActiveCustomTab()) } private fun onOmnibarPrivacyShieldButtonPressed() { - postBreakageReportingEvent() + contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData()) launchPrivacyDashboard(toggle = false) } @@ -2014,7 +2006,6 @@ class BrowserTabFragment : is Command.RefreshAndShowPrivacyProtectionEnabledConfirmation -> { webView?.let { safeWebView -> lifecycleScope.launch { - viewModel.privacyProtectionsUpdated(safeWebView) refresh() privacyProtectionEnabledConfirmation(it.domain) } @@ -2024,7 +2015,6 @@ class BrowserTabFragment : is Command.RefreshAndShowPrivacyProtectionDisabledConfirmation -> { webView?.let { safeWebView -> lifecycleScope.launch { - viewModel.privacyProtectionsUpdated(safeWebView) refresh() privacyProtectionDisabledConfirmation(it.domain) } @@ -3242,29 +3232,6 @@ class BrowserTabFragment : } }, ) - viewModel.configureWebView( - it, - object : WebViewCompatMessageCallback { - override fun process( - context: String, - featureName: String, - method: String, - id: String?, - data: JSONObject?, - onResponse: suspend (JSONObject) -> Unit, - ) { - viewModel.webViewCompatProcessJsCallbackMessage( - context = context, - featureName = featureName, - method = method, - id = id, - data = data, - onResponse = onResponse, - ) - } - }, - ) - duckPlayerScripts.register( it, object : JsMessageCallback() { diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt index 7bb2a2358bff..35a7a065d15a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt @@ -322,12 +322,7 @@ import com.duckduckgo.duckplayer.api.DuckPlayer import com.duckduckgo.duckplayer.api.DuckPlayer.DuckPlayerState.ENABLED import com.duckduckgo.feature.toggles.api.Toggle import com.duckduckgo.history.api.NavigationHistory -import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScriptPlugin import com.duckduckgo.js.messaging.api.JsCallbackData -import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin -import com.duckduckgo.js.messaging.api.SubscriptionEventData -import com.duckduckgo.js.messaging.api.WebMessagingPlugin -import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed.MALWARE import com.duckduckgo.malicioussiteprotection.api.MaliciousSiteProtection.Feed.PHISHING @@ -492,9 +487,6 @@ class BrowserTabViewModel @Inject constructor( private val externalIntentProcessingState: ExternalIntentProcessingState, private val vpnMenuStateProvider: VpnMenuStateProvider, private val webViewCompatWrapper: WebViewCompatWrapper, - private val addDocumentStartJavascriptPlugins: PluginPoint, - private val webMessagingPlugins: PluginPoint, - private val postMessageWrapperPlugins: PluginPoint, private val addressBarTrackersAnimationFeatureToggle: AddressBarTrackersAnimationFeatureToggle, private val autoconsentPixelManager: AutoconsentPixelManager, ) : ViewModel(), @@ -1941,11 +1933,6 @@ class BrowserTabViewModel @Inject constructor( evaluateSerpLogoState(url) } - viewModelScope.launch(dispatchers.io()) { - if (androidBrowserConfig.updateScriptOnPageFinished().isEnabled()) { - addDocumentStartJavaScript(webView) - } - } } private fun evaluateSerpLogoState(url: String?) { @@ -4254,75 +4241,6 @@ class BrowserTabViewModel @Inject constructor( } } - fun configureWebView( - webView: DuckDuckGoWebView, - callback: WebViewCompatMessageCallback?, - ) { - viewModelScope.launch { - addDocumentStartJavaScript(webView) - - callback?.let { - webMessagingPlugins.getPlugins().forEach { plugin -> - plugin.register(callback, webView) - } - } - } - } - - fun postContentScopeMessage( - eventData: SubscriptionEventData, - webView: WebView, - ) { - viewModelScope.launch { - postMessageWrapperPlugins - .getPlugins() - .firstOrNull { it.context == "contentScopeScripts" } - ?.postMessage(eventData, webView) - } - } - - private suspend fun addDocumentStartJavaScript(webView: WebView) { - addDocumentStartJavascriptPlugins.getPlugins().forEach { - it.addDocumentStartJavaScript( - webView, - ) - } - } - - suspend fun privacyProtectionsUpdated(webView: WebView) { - val updateScriptOnProtectionsChanged: Boolean - val stopLoadingBeforeUpdatingScript: Boolean - val updateScriptOnPageFinished: Boolean - - withContext(dispatchers.io()) { - updateScriptOnProtectionsChanged = androidBrowserConfig.updateScriptOnProtectionsChanged().isEnabled() - stopLoadingBeforeUpdatingScript = androidBrowserConfig.stopLoadingBeforeUpdatingScript().isEnabled() - updateScriptOnPageFinished = androidBrowserConfig.updateScriptOnPageFinished().isEnabled() - } - - if (!updateScriptOnProtectionsChanged) { - return - } - - if (stopLoadingBeforeUpdatingScript) { - withContext(dispatchers.main()) { - webView.stopLoading() - } - } - - if (!updateScriptOnPageFinished) { - addDocumentStartJavascriptPlugins - .getPlugins() - .filter { plugin -> - (plugin.context == "contentScopeScripts") - }.forEach { - it.addDocumentStartJavaScript(webView) - } - } else { - addDocumentStartJavaScript(webView) - } - } - fun onUserDismissedAutoCompleteInAppMessage() { viewModelScope.launch(dispatchers.io()) { autoComplete.userDismissedHistoryInAutoCompleteIAM() diff --git a/app/src/main/java/com/duckduckgo/app/pixels/remoteconfig/AndroidBrowserConfigFeature.kt b/app/src/main/java/com/duckduckgo/app/pixels/remoteconfig/AndroidBrowserConfigFeature.kt index e70d522d821b..b07a14bf8a59 100644 --- a/app/src/main/java/com/duckduckgo/app/pixels/remoteconfig/AndroidBrowserConfigFeature.kt +++ b/app/src/main/java/com/duckduckgo/app/pixels/remoteconfig/AndroidBrowserConfigFeature.kt @@ -181,15 +181,6 @@ interface AndroidBrowserConfigFeature { @Toggle.DefaultValue(DefaultFeatureValue.FALSE) fun vpnMenuItem(): Toggle - @Toggle.DefaultValue(TRUE) - fun updateScriptOnPageFinished(): Toggle - - @Toggle.DefaultValue(TRUE) - fun updateScriptOnProtectionsChanged(): Toggle - - @Toggle.DefaultValue(FALSE) - fun stopLoadingBeforeUpdatingScript(): Toggle - @Toggle.DefaultValue(TRUE) fun useUnifiedOmnibarLayout(): Toggle }