diff --git a/app/build.gradle b/app/build.gradle
index db9b9d54c548..e98816002a99 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -411,6 +411,7 @@ dependencies {
implementation project(':attributed-metrics-api')
implementation project(':attributed-metrics-impl')
+ internalImplementation project(':attributed-metrics-internal')
implementation project(':breakage-reporting-impl')
diff --git a/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsAttributedMetricsPlugin.kt b/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsAttributedMetricsPlugin.kt
new file mode 100644
index 000000000000..694140818283
--- /dev/null
+++ b/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsAttributedMetricsPlugin.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025 DuckDuckGo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.duckduckgo.app.statistics
+
+import android.content.Context
+import android.view.View
+import com.duckduckgo.app.attributed.metrics.internal.ui.AttributedMetricsSettingPlugin
+import com.duckduckgo.di.scopes.ActivityScope
+import com.squareup.anvil.annotations.ContributesMultibinding
+import javax.inject.Inject
+
+@ContributesMultibinding(ActivityScope::class)
+class StatisticsAttributedMetricsPlugin @Inject constructor() : AttributedMetricsSettingPlugin {
+
+ override fun getView(context: Context): View {
+ return StatisticsInternalInfoView(context)
+ }
+}
diff --git a/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsInternalInfoView.kt b/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsInternalInfoView.kt
new file mode 100644
index 000000000000..764167bb2d62
--- /dev/null
+++ b/app/src/internal/java/com/duckduckgo/app/statistics/StatisticsInternalInfoView.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2025 DuckDuckGo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.duckduckgo.app.statistics
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.LinearLayout
+import android.widget.Toast
+import com.duckduckgo.anvil.annotations.InjectWith
+import com.duckduckgo.app.browser.databinding.ViewStatisticsAttributedMetricsBinding
+import com.duckduckgo.app.global.install.AppInstallStore
+import com.duckduckgo.app.referral.AppReferrerDataStore
+import com.duckduckgo.app.statistics.store.StatisticsDataStore
+import com.duckduckgo.common.ui.viewbinding.viewBinding
+import com.duckduckgo.di.scopes.ViewScope
+import dagger.android.support.AndroidSupportInjection
+import java.text.SimpleDateFormat
+import java.util.*
+import javax.inject.Inject
+
+@InjectWith(ViewScope::class)
+class StatisticsInternalInfoView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyle: Int = 0,
+) : LinearLayout(context, attrs, defStyle) {
+
+ @Inject lateinit var store: StatisticsDataStore
+
+ @Inject lateinit var referrerDataStore: AppReferrerDataStore
+
+ @Inject lateinit var appInstallStore: AppInstallStore
+
+ private val binding: ViewStatisticsAttributedMetricsBinding by viewBinding()
+
+ private val dateETFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US).apply {
+ timeZone = TimeZone.getTimeZone("US/Eastern")
+ }
+ override fun onAttachedToWindow() {
+ AndroidSupportInjection.inject(this)
+ super.onAttachedToWindow()
+
+ binding.searchAtb.apply {
+ text = store.searchRetentionAtb ?: "unknown"
+ }
+
+ binding.searchAtbSave.setOnClickListener {
+ store.searchRetentionAtb?.let {
+ store.searchRetentionAtb = binding.searchAtb.text
+ }
+ Toast.makeText(this.context, "Search Atb updated", Toast.LENGTH_SHORT).show()
+ }
+
+ binding.originInput.apply {
+ text = referrerDataStore.utmOriginAttributeCampaign ?: "unknown"
+ }
+
+ binding.originInputSave.setOnClickListener {
+ referrerDataStore.utmOriginAttributeCampaign = binding.originInput.text.toString()
+ Toast.makeText(this.context, "Origin updated", Toast.LENGTH_SHORT).show()
+ }
+
+ binding.installDateInput.apply {
+ val timestamp = appInstallStore.installTimestamp
+ text = dateETFormat.format(Date(timestamp))
+ }
+
+ binding.installDateSave.setOnClickListener {
+ try {
+ val date = dateETFormat.parse(binding.installDateInput.text)
+ if (date != null) {
+ appInstallStore.installTimestamp = date.time
+ Toast.makeText(this.context, "Install date updated", Toast.LENGTH_SHORT).show()
+ } else {
+ Toast.makeText(this.context, "Invalid date format. Use yyyy-MM-dd", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: Exception) {
+ Toast.makeText(this.context, "Invalid date format. Use yyyy-MM-dd", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+}
diff --git a/app/src/internal/res/layout/view_statistics_attributed_metrics.xml b/app/src/internal/res/layout/view_statistics_attributed_metrics.xml
new file mode 100644
index 000000000000..c1f8c36b82f4
--- /dev/null
+++ b/app/src/internal/res/layout/view_statistics_attributed_metrics.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/attributed-metrics/attributed-metrics-internal/build.gradle b/attributed-metrics/attributed-metrics-internal/build.gradle
new file mode 100644
index 000000000000..6707ee5e481c
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/build.gradle
@@ -0,0 +1,41 @@
+plugins {
+ id 'com.android.library'
+ id 'kotlin-android'
+ id 'com.squareup.anvil'
+ id 'com.google.devtools.ksp'
+}
+
+apply from: "$rootProject.projectDir/gradle/android-library.gradle"
+
+android {
+ anvil {
+ generateDaggerFactories = true // default is false
+ }
+ namespace 'com.duckduckgo.attributed.metrics.internal'
+ testOptions {
+ unitTests {
+ includeAndroidResources = true
+ }
+ }
+}
+
+dependencies {
+ anvil project(':anvil-compiler')
+ implementation project(':anvil-annotations')
+ implementation project(':attributed-metrics-api')
+ implementation project(':attributed-metrics-impl')
+ implementation project(':di')
+ implementation project(':internal-features-api')
+ implementation project(':navigation-api')
+ implementation project(':common-utils')
+ implementation project(':design-system')
+
+ implementation AndroidX.appCompat
+ implementation AndroidX.constraintLayout
+ implementation Google.android.material
+ implementation Google.dagger
+
+ testImplementation project(path: ':common-test')
+ testImplementation "org.mockito.kotlin:mockito-kotlin:_"
+ testImplementation Testing.junit4
+}
diff --git a/attributed-metrics/attributed-metrics-internal/lint-baseline.xml b/attributed-metrics/attributed-metrics-internal/lint-baseline.xml
new file mode 100644
index 000000000000..1526a743bda6
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/lint-baseline.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/attributed-metrics/attributed-metrics-internal/src/main/AndroidManifest.xml b/attributed-metrics/attributed-metrics-internal/src/main/AndroidManifest.xml
new file mode 100644
index 000000000000..ade4ff78dfe9
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/src/main/AndroidManifest.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/AttributedMetricsDevSettingsFeatures.kt b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/AttributedMetricsDevSettingsFeatures.kt
new file mode 100644
index 000000000000..aaaeb9886959
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/AttributedMetricsDevSettingsFeatures.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.duckduckgo.app.attributed.metrics.internal
+
+import android.content.Context
+import com.duckduckgo.anvil.annotations.PriorityKey
+import com.duckduckgo.app.attributed.metrics.internal.ui.MainAttributedMetricsSettings
+import com.duckduckgo.di.scopes.AppScope
+import com.duckduckgo.internal.features.api.InternalFeaturePlugin
+import com.duckduckgo.navigation.api.GlobalActivityStarter
+import com.squareup.anvil.annotations.ContributesMultibinding
+import javax.inject.Inject
+
+@ContributesMultibinding(AppScope::class)
+@PriorityKey(InternalFeaturePlugin.ATTRIBUTED_METRICS_SETTINGS_PRIO_KEY)
+class AttributedMetricsDevSettingsFeatures @Inject constructor(
+ private val globalActivityStarter: GlobalActivityStarter,
+) : InternalFeaturePlugin {
+ override fun internalFeatureTitle(): String {
+ return "Attributed Metrics Settings"
+ }
+
+ override fun internalFeatureSubtitle(): String {
+ return "Attributed Metrics Dev Settings for internal users"
+ }
+
+ override fun onInternalFeatureClicked(activityContext: Context) {
+ globalActivityStarter.start(activityContext, MainAttributedMetricsSettings)
+ }
+}
diff --git a/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsDevSettingsActivity.kt b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsDevSettingsActivity.kt
new file mode 100644
index 000000000000..90cdcfd48ff6
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsDevSettingsActivity.kt
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.duckduckgo.app.attributed.metrics.internal.ui
+
+import android.os.Bundle
+import android.widget.Toast
+import androidx.lifecycle.lifecycleScope
+import com.duckduckgo.anvil.annotations.ContributeToActivityStarter
+import com.duckduckgo.anvil.annotations.InjectWith
+import com.duckduckgo.app.attributed.metrics.impl.AttributedMetricsState
+import com.duckduckgo.app.attributed.metrics.store.AttributedMetricsDateUtils
+import com.duckduckgo.app.attributed.metrics.store.EventDao
+import com.duckduckgo.app.attributed.metrics.store.EventEntity
+import com.duckduckgo.appbuildconfig.api.AppBuildConfig
+import com.duckduckgo.attributed.metrics.internal.databinding.ActivityAttributedMetricsDevSettingsBinding
+import com.duckduckgo.common.ui.DuckDuckGoActivity
+import com.duckduckgo.common.ui.viewbinding.viewBinding
+import com.duckduckgo.common.utils.plugins.PluginPoint
+import com.duckduckgo.di.scopes.ActivityScope
+import com.duckduckgo.navigation.api.GlobalActivityStarter
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@InjectWith(ActivityScope::class)
+@ContributeToActivityStarter(MainAttributedMetricsSettings::class)
+class AttributedMetricsDevSettingsActivity : DuckDuckGoActivity() {
+
+ private val binding: ActivityAttributedMetricsDevSettingsBinding by viewBinding()
+
+ @Inject
+ lateinit var eventDao: EventDao
+
+ @Inject
+ lateinit var dateUtils: AttributedMetricsDateUtils
+
+ @Inject
+ lateinit var appBuildConfig: AppBuildConfig
+
+ @Inject
+ lateinit var attributedMetricsState: AttributedMetricsState
+
+ @Inject
+ lateinit var settingsPlugins: PluginPoint
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ setupToolbar(binding.includeToolbar.toolbar)
+ setupViews()
+ setupPlugins()
+ }
+
+ private fun setupPlugins() {
+ settingsPlugins.getPlugins()
+ .mapNotNull { it.getView(this) }
+ .forEach { view ->
+ binding.settingsContainer.addView(view)
+ }
+ }
+
+ private fun setupViews() {
+ binding.addTestEventsButton.setOnClickListener {
+ addTestEvents()
+ }
+ lifecycleScope.launch {
+ binding.clientActive.setSecondaryText(if (attributedMetricsState.isActive()) "Yes" else "No")
+ binding.returningUser.setSecondaryText(if (appBuildConfig.isAppReinstall()) "Yes" else "No")
+ }
+ }
+
+ private fun addTestEvents() {
+ lifecycleScope.launch {
+ repeat(10) { daysAgo ->
+ val date = dateUtils.getDateMinusDays(daysAgo)
+ eventDao.insertEvent(EventEntity(eventName = "ddg_search_days", count = 1, day = date))
+ eventDao.insertEvent(EventEntity(eventName = "ddg_search", count = 1, day = date))
+ }
+ Toast.makeText(this@AttributedMetricsDevSettingsActivity, "Test events added", Toast.LENGTH_SHORT).show()
+ }
+ }
+}
+
+data object MainAttributedMetricsSettings : GlobalActivityStarter.ActivityParams {
+ private fun readResolve(): Any = MainAttributedMetricsSettings
+}
diff --git a/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsSettingPlugin.kt b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsSettingPlugin.kt
new file mode 100644
index 000000000000..b3c6e8ff7a1d
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/src/main/java/com/duckduckgo/app/attributed/metrics/internal/ui/AttributedMetricsSettingPlugin.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.duckduckgo.app.attributed.metrics.internal.ui
+
+import android.content.Context
+import android.view.View
+import com.duckduckgo.anvil.annotations.ContributesPluginPoint
+import com.duckduckgo.di.scopes.ActivityScope
+
+@ContributesPluginPoint(ActivityScope::class)
+interface AttributedMetricsSettingPlugin {
+ fun getView(context: Context): View
+}
diff --git a/attributed-metrics/attributed-metrics-internal/src/main/res/layout/activity_attributed_metrics_dev_settings.xml b/attributed-metrics/attributed-metrics-internal/src/main/res/layout/activity_attributed_metrics_dev_settings.xml
new file mode 100644
index 000000000000..5506a1b3ab27
--- /dev/null
+++ b/attributed-metrics/attributed-metrics-internal/src/main/res/layout/activity_attributed_metrics_dev_settings.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/internal-features/internal-features-api/src/main/java/com/duckduckgo/internal/features/api/InternalFeaturePlugin.kt b/internal-features/internal-features-api/src/main/java/com/duckduckgo/internal/features/api/InternalFeaturePlugin.kt
index 39853bd38722..b266a1224ca5 100644
--- a/internal-features/internal-features-api/src/main/java/com/duckduckgo/internal/features/api/InternalFeaturePlugin.kt
+++ b/internal-features/internal-features-api/src/main/java/com/duckduckgo/internal/features/api/InternalFeaturePlugin.kt
@@ -47,5 +47,6 @@ interface InternalFeaturePlugin {
const val ADS_SETTINGS_PRIO_KEY = 800
const val CRASH_ANR_SETTINGS_PRIO_KEY = 900
const val WEB_VIEW_DEV_SETTINGS_PRIO_KEY = 1_000
+ const val ATTRIBUTED_METRICS_SETTINGS_PRIO_KEY = 1_100
}
}