Skip to content

Commit

Permalink
Update UA logic (#4205)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshliebe authored Apr 26, 2024
1 parent 13a8a7d commit 6facadc
Show file tree
Hide file tree
Showing 53 changed files with 1,082 additions and 1,858 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ dependencies {

implementation project(':user-agent-api')
implementation project(':user-agent-impl')
implementation project(':user-agent-store')

implementation project(':js-messaging-api')
implementation project(':js-messaging-impl')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ import com.duckduckgo.common.test.CoroutineTestRule
import com.duckduckgo.feature.toggles.api.FeatureToggle
import com.duckduckgo.httpsupgrade.api.HttpsUpgrader
import com.duckduckgo.privacy.config.api.Gpc
import com.duckduckgo.privacy.config.api.UserAgent
import com.duckduckgo.privacy.config.impl.features.gpc.RealGpc.Companion.GPC_HEADER
import com.duckduckgo.request.filterer.api.RequestFilterer
import com.duckduckgo.user.agent.api.UserAgentProvider
import com.duckduckgo.user.agent.impl.RealUserAgentProvider
import com.duckduckgo.user.agent.impl.UserAgent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.*
import org.junit.Before
Expand Down Expand Up @@ -82,7 +82,6 @@ class WebViewRequestInterceptorTest {
fakeUserAgent,
fakeToggle,
fakeUserAllowListRepository,
FakeStatisticsDataStore(),
)

private var webView: WebView = mock()
Expand Down
27 changes: 4 additions & 23 deletions app/src/androidTest/java/com/duckduckgo/app/fakes/UserAgentFake.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2024 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,28 +16,9 @@

package com.duckduckgo.app.fakes

import com.duckduckgo.privacy.config.api.DefaultPolicy
import com.duckduckgo.privacy.config.api.DefaultPolicy.DDG
import com.duckduckgo.privacy.config.api.UserAgent
import com.duckduckgo.user.agent.impl.UserAgent

class UserAgentFake : UserAgent {
override fun isAnApplicationException(url: String): Boolean = false

override fun isAVersionException(url: String): Boolean = false

override fun isADefaultException(url: String): Boolean = false

override fun defaultPolicy(): DefaultPolicy = DDG

override fun isADdgDefaultSite(url: String): Boolean = false

override fun isADdgFixedSite(url: String): Boolean = false

override fun closestUserAgentEnabled(): Boolean = false

override fun ddgFixedUserAgentEnabled(): Boolean = false

override fun isClosestUserAgentVersion(version: String): Boolean = false

override fun isDdgFixedUserAgentVersion(version: String): Boolean = false
override fun useLegacyUserAgent(url: String): Boolean = false
override fun isException(url: String): Boolean = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import com.duckduckgo.common.test.CoroutineTestRule
import com.duckduckgo.common.test.api.FakeChain
import com.duckduckgo.common.utils.device.ContextDeviceInfo
import com.duckduckgo.feature.toggles.api.FeatureToggle
import com.duckduckgo.privacy.config.api.UserAgent
import com.duckduckgo.user.agent.api.UserAgentProvider
import com.duckduckgo.user.agent.impl.RealUserAgentProvider
import com.duckduckgo.user.agent.impl.UserAgent
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -60,7 +60,6 @@ class ApiRequestInterceptorTest {
fakeUserAgent,
fakeToggle,
fakeUserAllowListRepository,
mock(),
)

testee = ApiRequestInterceptor(
Expand Down Expand Up @@ -88,7 +87,7 @@ class ApiRequestInterceptorTest {
val response = testee.intercept(fakeChain)
val header = response.request.header(Header.USER_AGENT)!!
val regex =
"Mozilla/.* \\(Linux; Android.*\\) AppleWebKit/.* \\(KHTML, like Gecko\\) Version/.* Chrome/.* Mobile DuckDuckGo/.* Safari/.*".toRegex()
"Mozilla/.* \\(Linux; Android.*\\) AppleWebKit/.* \\(KHTML, like Gecko\\) Chrome/.* Mobile Safari/.*".toRegex()
assertTrue(header.matches(regex))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ import com.duckduckgo.httpsupgrade.api.HttpsUpgrader
import com.duckduckgo.privacy.config.api.ContentBlocking
import com.duckduckgo.privacy.config.api.Gpc
import com.duckduckgo.privacy.config.api.TrackerAllowlist
import com.duckduckgo.privacy.config.api.UserAgent
import com.duckduckgo.request.filterer.api.RequestFilterer
import com.duckduckgo.user.agent.api.UserAgentProvider
import com.duckduckgo.user.agent.impl.RealUserAgentProvider
import com.duckduckgo.user.agent.impl.UserAgent
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -114,7 +114,6 @@ class DomainsReferenceTest(private val testCase: TestCase) {
fakeUserAgent,
fakeToggle,
fakeUserAllowListRepository,
mock(),
)
private val mockGpc: Gpc = mock()
private val mockAdClickManager: AdClickManager = mock()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ import com.duckduckgo.httpsupgrade.api.HttpsUpgrader
import com.duckduckgo.privacy.config.api.ContentBlocking
import com.duckduckgo.privacy.config.api.Gpc
import com.duckduckgo.privacy.config.api.TrackerAllowlist
import com.duckduckgo.privacy.config.api.UserAgent
import com.duckduckgo.request.filterer.api.RequestFilterer
import com.duckduckgo.user.agent.api.UserAgentProvider
import com.duckduckgo.user.agent.impl.RealUserAgentProvider
import com.duckduckgo.user.agent.impl.UserAgent
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -109,7 +109,6 @@ class SurrogatesReferenceTest(private val testCase: TestCase) {
fakeUserAgent,
fakeToggle,
fakeUserAllowListRepository,
mock(),
)
private val mockGpc: Gpc = mock()
private val mockAdClickManager: AdClickManager = mock()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,8 @@ class DevSettingsActivity : DuckDuckGoActivity() {
val popup = PopupMenu(layoutInflater, layout.popup_window_user_agent_override)
val view = popup.contentView
popup.apply {
onMenuItemClicked(view.findViewById(R.id.noAppId)) { viewModel.onUserAgentSelected(UAOverride.NO_APP_ID) }
onMenuItemClicked(view.findViewById(R.id.noVersion)) { viewModel.onUserAgentSelected(UAOverride.NO_VERSION) }
onMenuItemClicked(view.findViewById(R.id.chrome)) { viewModel.onUserAgentSelected(UAOverride.CHROME) }
onMenuItemClicked(view.findViewById(R.id.firefox)) { viewModel.onUserAgentSelected(UAOverride.FIREFOX) }
onMenuItemClicked(view.findViewById(R.id.duckDuckGo)) { viewModel.onUserAgentSelected(UAOverride.DDG) }
onMenuItemClicked(view.findViewById(R.id.defaultUA)) { viewModel.onUserAgentSelected(UAOverride.DEFAULT) }
onMenuItemClicked(view.findViewById(R.id.webView)) { viewModel.onUserAgentSelected(UAOverride.WEBVIEW) }
}
popup.show(binding.root, binding.overrideUserAgentSelector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.duckduckgo.app.dev.settings

import com.duckduckgo.app.dev.settings.db.DevSettingsDataStore
import com.duckduckgo.app.dev.settings.db.UAOverride
import com.duckduckgo.common.utils.device.DeviceInfo
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.user.agent.api.UserAgentInterceptor
import com.squareup.anvil.annotations.ContributesMultibinding
Expand All @@ -29,21 +28,14 @@ import javax.inject.Provider
@ContributesMultibinding(AppScope::class)
class InternalUAInterceptor @Inject constructor(
private val devSettingsDataStore: DevSettingsDataStore,
device: DeviceInfo,
@Named("defaultUserAgent") private val defaultUserAgent: Provider<String>,
) : UserAgentInterceptor {

private val applicationComponent = "DuckDuckGo/${device.majorAppVersion}"
private val version = Regex("(Version/[^ ]+) *")

override fun intercept(userAgent: String): String {
if (!devSettingsDataStore.overrideUA) return userAgent

return when (devSettingsDataStore.selectedUA) {
UAOverride.NO_APP_ID -> userAgent.replace(applicationComponent, "")
UAOverride.NO_VERSION -> userAgent.replace(version, "")
UAOverride.DDG -> userAgent
UAOverride.CHROME -> userAgent.replace(applicationComponent, "").replace(version, "")
UAOverride.DEFAULT -> userAgent
UAOverride.FIREFOX -> "Mozilla/5.0 (Android 11; Mobile; rv:94.0) Gecko/94.0 Firefox/94.0"
UAOverride.WEBVIEW -> defaultUserAgent.get()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ class DevSettingsSharedPreferences @Inject constructor(private val context: Cont
private val preferences: SharedPreferences by lazy { context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE) }

private fun selectedUASavedValue(): UAOverride {
val savedValue = preferences.getString(KEY_SELECTED_UA, null) ?: return UAOverride.DDG
return UAOverride.valueOf(savedValue)
runCatching {
val savedValue = preferences.getString(KEY_SELECTED_UA, null) ?: return UAOverride.DEFAULT
return UAOverride.valueOf(savedValue)
}
return UAOverride.DEFAULT
}
companion object {
const val FILENAME = "com.duckduckgo.app.dev_settings_activity.dev_settings"
Expand All @@ -58,10 +61,7 @@ class DevSettingsSharedPreferences @Inject constructor(private val context: Cont
}

enum class UAOverride {
NO_APP_ID,
NO_VERSION,
CHROME,
FIREFOX,
DDG,
DEFAULT,
WEBVIEW,
}
22 changes: 2 additions & 20 deletions app/src/internal/res/layout/popup_window_user_agent_override.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,10 @@
android:background="@drawable/popup_menu_bg">

<com.duckduckgo.common.ui.view.PopupMenuItemView
android:id="@+id/noAppId"
android:id="@+id/defaultUA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:primaryText="@string/devSettingsScreenUserAgentNoAppId" />

<com.duckduckgo.common.ui.view.PopupMenuItemView
android:id="@+id/noVersion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:primaryText="@string/devSettingsScreenUserAgentNoVersion" />

<com.duckduckgo.common.ui.view.PopupMenuItemView
android:id="@+id/chrome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:primaryText="@string/devSettingsScreenUserAgentChrome" />

<com.duckduckgo.common.ui.view.PopupMenuItemView
android:id="@+id/duckDuckGo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:primaryText="@string/devSettingsScreenUserAgentDuckDuckGo" />
app:primaryText="@string/devSettingsScreenUserAgentDefault" />

<com.duckduckgo.common.ui.view.PopupMenuItemView
android:id="@+id/firefox"
Expand Down
5 changes: 1 addition & 4 deletions app/src/internal/res/values/donottranslate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@
<string name="devSettingsScreenPrivacyRemoteConfigUrlOverride">Override Privacy Remote Config URL</string>
<string name="devSettingsScreenPrivacyRemoteConfigUrlOverrideSubtitle">Click here to customize the Privacy Remote Config URL</string>
<string name="devSettingsScreenUserAgentSelectorTitle">UserAgent</string>
<string name="devSettingsScreenUserAgentNoAppId">Omit DuckDuckGo AppId</string>
<string name="devSettingsScreenUserAgentNoVersion">Omit Webview Version</string>
<string name="devSettingsScreenUserAgentChrome">Chrome (no appId and no Version)</string>
<string name="devSettingsScreenUserAgentFirefox">Firefox</string>
<string name="devSettingsScreenUserAgentDuckDuckGo">DDG Default</string>
<string name="devSettingsScreenUserAgentDefault">Default</string>
<string name="devSettingsScreenUserAgentWebView">UA WebView</string>

<!-- Privacy Audit settings -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ enum class PrivacyFeatureName(val value: String) {
DrmFeatureName("eme"),
AmpLinksFeatureName("ampLinks"),
TrackingParametersFeatureName("trackingParameters"),
UserAgentFeatureName("customUserAgent"),
}

const val PRIVACY_REMOTE_CONFIG_URL = "https://staticcdn.duckduckgo.com/trackerblocking/config/v4/android-config.json"

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ import com.duckduckgo.privacy.config.store.features.trackingparameters.RealTrack
import com.duckduckgo.privacy.config.store.features.trackingparameters.TrackingParametersRepository
import com.duckduckgo.privacy.config.store.features.unprotectedtemporary.RealUnprotectedTemporaryRepository
import com.duckduckgo.privacy.config.store.features.unprotectedtemporary.UnprotectedTemporaryRepository
import com.duckduckgo.privacy.config.store.features.useragent.RealUserAgentRepository
import com.duckduckgo.privacy.config.store.features.useragent.UserAgentRepository
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -189,15 +187,4 @@ object DatabaseModule {
): TrackingParametersRepository {
return RealTrackingParametersRepository(database, appCoroutineScope, dispatcherProvider, isMainProcess)
}

@SingleInstanceIn(AppScope::class)
@Provides
fun provideUserAgentRepository(
database: PrivacyConfigDatabase,
@AppCoroutineScope appCoroutineScope: CoroutineScope,
dispatcherProvider: DispatcherProvider,
@IsMainProcess isMainProcess: Boolean,
): UserAgentRepository {
return RealUserAgentRepository(database, appCoroutineScope, dispatcherProvider, isMainProcess)
}
}
Loading

0 comments on commit 6facadc

Please sign in to comment.