mirror of
https://github.com/thunderbird/thunderbird-android.git
synced 2024-09-19 19:52:14 +02:00
Merge pull request #8130 from thunderbird/telemetry_setting
Add setting for app telemetry
This commit is contained in:
commit
dc34b8f4a7
@ -23,6 +23,7 @@ dependencies {
|
||||
implementation(projects.feature.widget.messageList)
|
||||
implementation(projects.feature.widget.shortcut)
|
||||
implementation(projects.feature.widget.unread)
|
||||
implementation(projects.feature.telemetry.api)
|
||||
|
||||
implementation(libs.androidx.work.runtime)
|
||||
|
||||
|
@ -7,10 +7,12 @@ import app.k9mail.core.featureflag.FeatureFlagFactory
|
||||
import app.k9mail.core.ui.theme.api.FeatureThemeProvider
|
||||
import app.k9mail.core.ui.theme.api.ThemeProvider
|
||||
import app.k9mail.dev.developmentModuleAdditions
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.feature.widget.shortcut.LauncherShortcutActivity
|
||||
import app.k9mail.featureflag.K9FeatureFlagFactory
|
||||
import app.k9mail.provider.K9AppNameProvider
|
||||
import app.k9mail.provider.K9FeatureThemeProvider
|
||||
import app.k9mail.telemetry.K9TelemetryManager
|
||||
import app.k9mail.widget.appWidgetModule
|
||||
import com.fsck.k9.AppConfig
|
||||
import com.fsck.k9.BuildConfig
|
||||
@ -33,6 +35,7 @@ val appModule = module {
|
||||
single<ThemeProvider> { K9ThemeProvider() }
|
||||
single<FeatureThemeProvider> { K9FeatureThemeProvider() }
|
||||
single<FeatureFlagFactory> { K9FeatureFlagFactory() }
|
||||
single<TelemetryManager> { K9TelemetryManager() }
|
||||
|
||||
developmentModuleAdditions()
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package app.k9mail.telemetry
|
||||
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
|
||||
class K9TelemetryManager : TelemetryManager {
|
||||
override fun isTelemetryFeatureIncluded(): Boolean = false
|
||||
}
|
@ -23,6 +23,7 @@ dependencies {
|
||||
implementation(projects.feature.widget.messageList)
|
||||
implementation(projects.feature.widget.shortcut)
|
||||
implementation(projects.feature.widget.unread)
|
||||
implementation(projects.feature.telemetry.glean)
|
||||
|
||||
implementation(libs.androidx.work.runtime)
|
||||
|
||||
|
@ -5,6 +5,8 @@ import app.k9mail.core.common.provider.AppNameProvider
|
||||
import app.k9mail.core.featureflag.FeatureFlagFactory
|
||||
import app.k9mail.core.ui.theme.api.FeatureThemeProvider
|
||||
import app.k9mail.core.ui.theme.api.ThemeProvider
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.feature.telemetry.glean.GleanTelemetryManager
|
||||
import app.k9mail.feature.widget.shortcut.LauncherShortcutActivity
|
||||
import com.fsck.k9.AppConfig
|
||||
import com.fsck.k9.activity.MessageCompose
|
||||
@ -32,6 +34,7 @@ val appModule = module {
|
||||
single<ThemeProvider> { TbThemeProvider() }
|
||||
single<FeatureThemeProvider> { TbFeatureThemeProvider() }
|
||||
single<FeatureFlagFactory> { TbFeatureFlagFactory() }
|
||||
single<TelemetryManager> { GleanTelemetryManager() }
|
||||
|
||||
developmentModuleAdditions()
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
>
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM19,19H5V5h14V19z"
|
||||
/>
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,12h2v5h-2z"
|
||||
/>
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15,7h2v10h-2z"
|
||||
/>
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11,14h2v3h-2z"
|
||||
/>
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11,10h2v2h-2z"
|
||||
/>
|
||||
|
||||
</vector>
|
3
feature/telemetry/api/build.gradle.kts
Normal file
3
feature/telemetry/api/build.gradle.kts
Normal file
@ -0,0 +1,3 @@
|
||||
plugins {
|
||||
id(ThunderbirdPlugins.Library.jvm)
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package app.k9mail.feature.telemetry.api
|
||||
|
||||
interface TelemetryManager {
|
||||
/**
|
||||
* Returns `true` if the app has a telemetry feature included.
|
||||
*/
|
||||
fun isTelemetryFeatureIncluded(): Boolean
|
||||
}
|
12
feature/telemetry/glean/build.gradle.kts
Normal file
12
feature/telemetry/glean/build.gradle.kts
Normal file
@ -0,0 +1,12 @@
|
||||
plugins {
|
||||
id(ThunderbirdPlugins.Library.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.k9mail.feature.telemetry.glean"
|
||||
resourcePrefix = "telemetry_glean_"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.feature.telemetry.api)
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package app.k9mail.feature.telemetry.glean
|
||||
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
|
||||
class GleanTelemetryManager : TelemetryManager {
|
||||
override fun isTelemetryFeatureIncluded(): Boolean = true
|
||||
}
|
@ -19,6 +19,7 @@ dependencies {
|
||||
api(projects.legacy.search)
|
||||
|
||||
implementation(projects.plugins.openpgpApiLib.openpgpApi)
|
||||
implementation(projects.feature.telemetry.api)
|
||||
|
||||
api(libs.androidx.annotation)
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.fsck.k9
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.legacy.account.Account
|
||||
import app.k9mail.legacy.account.Account.SortType
|
||||
import app.k9mail.legacy.di.DI
|
||||
@ -20,6 +21,7 @@ import timber.log.Timber.DebugTree
|
||||
// TODO "Use GeneralSettingsManager and GeneralSettings instead"
|
||||
object K9 : EarlyInit {
|
||||
private val generalSettingsManager: RealGeneralSettingsManager by inject()
|
||||
private val telemetryManager: TelemetryManager by inject()
|
||||
|
||||
/**
|
||||
* If this is `true`, various development settings will be enabled.
|
||||
@ -267,6 +269,11 @@ object K9 : EarlyInit {
|
||||
@JvmStatic
|
||||
var swipeLeftAction: SwipeAction = SwipeAction.ToggleRead
|
||||
|
||||
// TODO: This is a feature-specific setting that doesn't need to be available to apps that don't include the
|
||||
// feature. Extract `Storage` and `StorageEditor` to a separate module so feature modules can retrieve and store
|
||||
// their own settings.
|
||||
var isTelemetryEnabled = false
|
||||
|
||||
val isQuietTime: Boolean
|
||||
get() {
|
||||
if (!isQuietTimeEnabled) {
|
||||
@ -384,6 +391,10 @@ object K9 : EarlyInit {
|
||||
|
||||
swipeRightAction = storage.getEnum("swipeRightAction", SwipeAction.ToggleSelection)
|
||||
swipeLeftAction = storage.getEnum("swipeLeftAction", SwipeAction.ToggleRead)
|
||||
|
||||
if (telemetryManager.isTelemetryFeatureIncluded()) {
|
||||
isTelemetryEnabled = storage.getBoolean("enableTelemetry", true)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun save(editor: StorageEditor) {
|
||||
@ -448,6 +459,10 @@ object K9 : EarlyInit {
|
||||
editor.putEnum("swipeRightAction", swipeRightAction)
|
||||
editor.putEnum("swipeLeftAction", swipeLeftAction)
|
||||
|
||||
if (telemetryManager.isTelemetryFeatureIncluded()) {
|
||||
editor.putBoolean("enableTelemetry", isTelemetryEnabled)
|
||||
}
|
||||
|
||||
fontSizes.save(editor)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.util.TreeMap;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager;
|
||||
import app.k9mail.legacy.account.Account;
|
||||
import app.k9mail.legacy.account.Account.SortType;
|
||||
import app.k9mail.legacy.di.DI;
|
||||
@ -48,6 +49,8 @@ class GeneralSettingsDescriptions {
|
||||
static final Map<String, TreeMap<Integer, SettingsDescription<?>>> SETTINGS;
|
||||
private static final Map<Integer, SettingsUpgrader> UPGRADERS;
|
||||
|
||||
private static final TelemetryManager telemetryManager = DI.get(TelemetryManager.class);
|
||||
|
||||
static {
|
||||
Map<String, TreeMap<Integer, SettingsDescription<?>>> s = new LinkedHashMap<>();
|
||||
|
||||
@ -298,6 +301,13 @@ class GeneralSettingsDescriptions {
|
||||
new EnumSetting<>(PostMarkAsUnreadNavigation.class, PostMarkAsUnreadNavigation.ReturnToMessageList))
|
||||
));
|
||||
|
||||
// TODO: Add a way to properly support feature-specific settings.
|
||||
if (telemetryManager.isTelemetryFeatureIncluded()) {
|
||||
s.put("enableTelemetry", Settings.versions(
|
||||
new V(97, new BooleanSetting(true))
|
||||
));
|
||||
}
|
||||
|
||||
SETTINGS = Collections.unmodifiableMap(s);
|
||||
|
||||
Map<Integer, SettingsUpgrader> u = new HashMap<>();
|
||||
|
@ -33,7 +33,7 @@ class Settings {
|
||||
*
|
||||
* @see SettingsExporter
|
||||
*/
|
||||
public static final int VERSION = 96;
|
||||
public static final int VERSION = 97;
|
||||
|
||||
static Map<String, Object> validate(int version, Map<String, TreeMap<Integer, SettingsDescription<?>>> settings,
|
||||
Map<String, String> importedSettings, boolean useDefaultValues) {
|
||||
|
@ -2,6 +2,7 @@ package com.fsck.k9
|
||||
|
||||
import android.app.Application
|
||||
import androidx.work.WorkManager
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.legacy.di.DI
|
||||
import com.fsck.k9.backend.BackendManager
|
||||
import com.fsck.k9.controller.ControllerExtension
|
||||
@ -43,4 +44,9 @@ val testModule = module {
|
||||
single { mock<NotificationStrategy>() }
|
||||
single(named("controllerExtensions")) { emptyList<ControllerExtension>() }
|
||||
single { mock<WorkManager>() }
|
||||
single<TelemetryManager> {
|
||||
object : TelemetryManager {
|
||||
override fun isTelemetryFeatureIncluded(): Boolean = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ dependencies {
|
||||
|
||||
testImplementation(projects.mail.testing)
|
||||
testImplementation(projects.legacy.testing)
|
||||
testImplementation(projects.feature.telemetry.api)
|
||||
testImplementation(libs.robolectric)
|
||||
testImplementation(libs.commons.io)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.fsck.k9.storage
|
||||
|
||||
import android.app.Application
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.legacy.di.DI
|
||||
import com.fsck.k9.AppConfig
|
||||
import com.fsck.k9.Core
|
||||
@ -32,4 +33,9 @@ val testModule = module {
|
||||
single { mock<EncryptionExtractor>() }
|
||||
single<StoragePersister> { K9StoragePersister(get()) }
|
||||
single { mock<BackendManager>() }
|
||||
single<TelemetryManager> {
|
||||
object : TelemetryManager {
|
||||
override fun isTelemetryFeatureIncluded(): Boolean = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ dependencies {
|
||||
// TODO: Remove AccountOauth dependency
|
||||
implementation(projects.feature.account.oauth)
|
||||
implementation(projects.feature.settings.import)
|
||||
implementation(projects.feature.telemetry.api)
|
||||
|
||||
compileOnly(projects.mail.protocols.imap)
|
||||
|
||||
|
@ -45,6 +45,7 @@ class GeneralSettingsDataStore(
|
||||
"debug_logging" -> K9.isDebugLoggingEnabled
|
||||
"sensitive_logging" -> K9.isSensitiveDebugLoggingEnabled
|
||||
"volume_navigation" -> K9.isUseVolumeKeysForNavigation
|
||||
"enable_telemetry" -> K9.isTelemetryEnabled
|
||||
else -> defValue
|
||||
}
|
||||
}
|
||||
@ -74,6 +75,7 @@ class GeneralSettingsDataStore(
|
||||
"debug_logging" -> K9.isDebugLoggingEnabled = value
|
||||
"sensitive_logging" -> K9.isSensitiveDebugLoggingEnabled = value
|
||||
"volume_navigation" -> K9.isUseVolumeKeysForNavigation = value
|
||||
"enable_telemetry" -> K9.isTelemetryEnabled = value
|
||||
else -> return
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,12 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.ui.base.extensions.withArguments
|
||||
import com.fsck.k9.ui.observe
|
||||
import com.fsck.k9.ui.settings.remove
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.takisoft.preferencex.PreferenceFragmentCompat
|
||||
import org.koin.android.ext.android.inject
|
||||
@ -19,6 +22,7 @@ import com.fsck.k9.core.R as CoreR
|
||||
class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
||||
private val viewModel: GeneralSettingsViewModel by viewModel()
|
||||
private val dataStore: GeneralSettingsDataStore by inject()
|
||||
private val telemetryManager: TelemetryManager by inject()
|
||||
|
||||
private var rootKey: String? = null
|
||||
private var currentUiState: GeneralSettingsUiState? = null
|
||||
@ -37,6 +41,7 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
||||
setPreferencesFromResource(R.xml.general_settings, rootKey)
|
||||
|
||||
initializeTheme()
|
||||
initializeDataCollection()
|
||||
|
||||
viewModel.uiState.observe(this) { uiState ->
|
||||
updateUiState(uiState)
|
||||
@ -80,6 +85,12 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeDataCollection() {
|
||||
if (!telemetryManager.isTelemetryFeatureIncluded()) {
|
||||
findPreference<Preference>(PREFERENCE_DATA_COLLECTION)?.remove()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateUiState(uiState: GeneralSettingsUiState) {
|
||||
val oldUiState = currentUiState
|
||||
currentUiState = uiState
|
||||
@ -119,6 +130,7 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
||||
companion object {
|
||||
private const val PREFERENCE_THEME = "theme"
|
||||
private const val PREFERENCE_SCREEN_DEBUGGING = "debug_preferences"
|
||||
private const val PREFERENCE_DATA_COLLECTION = "data_collection"
|
||||
|
||||
fun create(rootKey: String? = null) = GeneralSettingsFragment().withArguments(ARG_PREFERENCE_ROOT to rootKey)
|
||||
}
|
||||
|
@ -1114,4 +1114,11 @@ You can keep this message and use it as a backup for your secret key. If you wan
|
||||
|
||||
<!-- For unread messages the first line of a message list item is modified by this to improve the experience for people with screen readers. -->
|
||||
<string name="message_list_content_description_unread_prefix">unread, %s</string>
|
||||
|
||||
<!-- Name of the "data collection" section in the general settings screen -->
|
||||
<string name="settings_ui_data_collection">Data collection</string>
|
||||
<!-- Title of the "Usage and technical data" setting used in the "data collection" section of the general settings screen -->
|
||||
<string name="settings_ui_telemetry_title">Usage and technical data</string>
|
||||
<!-- Description of the "Usage and technical data" setting used in the "data collection" section of the general settings screen -->
|
||||
<string name="settings_ui_telemetry_description">Shares performance, usage, hardware and customization data about this app with Mozilla to help us make Thunderbird better</string>
|
||||
</resources>
|
||||
|
@ -514,6 +514,21 @@
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_analytics"
|
||||
android:key="data_collection"
|
||||
android:title="@string/settings_ui_data_collection"
|
||||
search:ignore="true"
|
||||
>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="enable_telemetry"
|
||||
android:summary="@string/settings_ui_telemetry_description"
|
||||
android:title="@string/settings_ui_telemetry_title"
|
||||
/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_bug_report"
|
||||
android:key="debug_preferences"
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.fsck.k9
|
||||
|
||||
import android.app.Application
|
||||
import app.k9mail.feature.telemetry.api.TelemetryManager
|
||||
import app.k9mail.legacy.di.DI
|
||||
import com.fsck.k9.preferences.InMemoryStoragePersister
|
||||
import com.fsck.k9.preferences.StoragePersister
|
||||
@ -26,4 +27,9 @@ val testModule = module {
|
||||
single { AppConfig(emptyList()) }
|
||||
single<CoreResourceProvider> { TestCoreResourceProvider() }
|
||||
single<StoragePersister> { InMemoryStoragePersister() }
|
||||
single<TelemetryManager> {
|
||||
object : TelemetryManager {
|
||||
override fun isTelemetryFeatureIncluded(): Boolean = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,11 @@ include(
|
||||
":feature:migration:provider",
|
||||
)
|
||||
|
||||
include(
|
||||
":feature:telemetry:api",
|
||||
":feature:telemetry:glean",
|
||||
)
|
||||
|
||||
include(
|
||||
":core:common",
|
||||
":core:featureflags",
|
||||
|
Loading…
Reference in New Issue
Block a user