For #14034: Add debug preference to override AMO collection in Nightly

pull/184/head
Christian Sadilek 4 years ago
parent a92356fe00
commit d4ab728cff

@ -17,8 +17,10 @@ import mozilla.components.feature.addons.update.DefaultAddonUpdater
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.migration.state.MigrationStore
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.metrics.AppStartupTelemetry
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.utils.ClipboardHandler
import org.mozilla.fenix.utils.Mockable
import org.mozilla.fenix.utils.Settings
@ -71,14 +73,26 @@ class Components(private val context: Context) {
}
val addonCollectionProvider by lazy {
if (!BuildConfig.AMO_COLLECTION.isNullOrEmpty()) {
// Check if we have a customized (overridden) AMO collection (only supported in Nightly)
if (Config.channel.isNightlyOrDebug && context.settings().amoCollectionOverrideConfigured()) {
AddonCollectionProvider(
context,
core.client,
collectionUser = context.settings().overrideAmoUser,
collectionName = context.settings().overrideAmoCollection
)
}
// Use build config otherwise
else if (!BuildConfig.AMO_COLLECTION.isNullOrEmpty()) {
AddonCollectionProvider(
context,
core.client,
collectionName = BuildConfig.AMO_COLLECTION,
maxCacheAgeInMinutes = DAY_IN_MINUTES
)
} else {
}
// Fall back to defaults
else {
AddonCollectionProvider(context, core.client, maxCacheAgeInMinutes = DAY_IN_MINUTES)
}
}

@ -6,13 +6,16 @@ package org.mozilla.fenix.settings
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.provider.Settings
import android.view.LayoutInflater
import android.widget.Toast
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavDirections
import androidx.navigation.findNavController
@ -20,6 +23,8 @@ import androidx.navigation.fragment.navArgs
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.amo_collection_override_dialog.view.*
import kotlinx.android.synthetic.main.fragment_installed_add_on_details.view.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -28,6 +33,7 @@ import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.view.showKeyboard
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
@ -43,6 +49,7 @@ import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.account.AccountUiView
import org.mozilla.fenix.utils.Settings
import kotlin.system.exitProcess
@Suppress("LargeClass", "TooManyFunctions")
@ -304,6 +311,41 @@ class SettingsFragment : PreferenceFragmentCompat() {
resources.getString(R.string.pref_key_debug_settings) -> {
SettingsFragmentDirections.actionSettingsFragmentToSecretSettingsFragment()
}
resources.getString(R.string.pref_key_override_amo_collection) -> {
val context = requireContext()
val dialogView = LayoutInflater.from(context).inflate(R.layout.amo_collection_override_dialog, null)
AlertDialog.Builder(context).apply {
setTitle(context.getString(R.string.preferences_customize_amo_collection))
setView(dialogView)
setNegativeButton(R.string.customize_addon_collection_cancel) { dialog: DialogInterface, _ ->
dialog.cancel()
}
setPositiveButton(R.string.customize_addon_collection_ok) { _, _ ->
context.settings().overrideAmoUser = dialogView.custom_amo_user.text.toString()
context.settings().overrideAmoCollection = dialogView.custom_amo_collection.text.toString()
Toast.makeText(
context,
getString(R.string.toast_customize_addon_collection_done),
Toast.LENGTH_LONG
).show()
Handler().postDelayed({
exitProcess(0)
}, AMO_COLLECTION_OVERRIDE_EXIT_DELAY)
}
dialogView.custom_amo_collection.setText(context.settings().overrideAmoCollection)
dialogView.custom_amo_user.setText(context.settings().overrideAmoUser)
dialogView.custom_amo_user.requestFocus()
dialogView.custom_amo_user.showKeyboard()
create()
}.show()
null
}
else -> null
}
directions?.let { navigateFromSettings(directions) }
@ -374,12 +416,14 @@ class SettingsFragment : PreferenceFragmentCompat() {
findPreference<Preference>(
getPreferenceKey(R.string.pref_key_debug_settings)
)?.isVisible = requireContext().settings().showSecretDebugMenuThisSession
setupAmoCollectionOverridePreference(requireContext().settings())
}
private fun getClickListenerForMakeDefaultBrowser(): Preference.OnPreferenceClickListener {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Preference.OnPreferenceClickListener {
val intent = Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
val intent = Intent(android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
startActivity(intent)
true
}
@ -446,8 +490,23 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
}
@VisibleForTesting
internal fun setupAmoCollectionOverridePreference(settings: Settings) {
val preferenceAmoCollectionOverride =
findPreference<Preference>(getPreferenceKey(R.string.pref_key_override_amo_collection))
val show = (Config.channel.isNightlyOrDebug && (
settings.amoCollectionOverrideConfigured() || settings.showSecretDebugMenuThisSession)
)
preferenceAmoCollectionOverride?.apply {
isVisible = show
summary = settings.overrideAmoCollection.ifEmpty { null }
}
}
companion object {
private const val SCROLL_INDICATOR_DELAY = 10L
private const val FXA_SYNC_OVERRIDE_EXIT_DELAY = 2000L
private const val AMO_COLLECTION_OVERRIDE_EXIT_DELAY = 3000L
}
}

@ -886,6 +886,20 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = ""
)
var overrideAmoUser by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_override_amo_user),
default = ""
)
var overrideAmoCollection by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_override_amo_collection),
default = ""
)
fun amoCollectionOverrideConfigured(): Boolean {
return overrideAmoUser.isNotEmpty() || overrideAmoCollection.isNotEmpty()
}
val topSitesSize by intPreference(
appContext.getPreferenceKey(R.string.pref_key_top_sites_size),
default = 0

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/custom_amo_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/customize_addon_collection_user_hint"
android:singleLine="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:textColor="?primaryText"/>
<EditText
android:id="@+id/custom_amo_collection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/customize_addon_collection_hint"
android:singleLine="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textColor="?primaryText"/>
</LinearLayout>

@ -35,6 +35,8 @@
<string name="pref_key_delete_browsing_data_on_quit_categories" translatable="false">pref_key_delete_browsing_data_on_quit_categories</string>
<string name="pref_key_last_known_mode_private" translatable="false">pref_key_last_known_mode_private</string>
<string name="pref_key_addons" translatable="false">pref_key_addons</string>
<string name="pref_key_override_amo_user" translatable="false">pref_key_override_amo_user</string>
<string name="pref_key_override_amo_collection" translatable="false">pref_key_override_amo_collection</string>
<string name="pref_key_last_maintenance" translatable="false">pref_key_last_maintenance</string>
<string name="pref_key_help" translatable="false">pref_key_help</string>
<string name="pref_key_rate" translatable="false">pref_key_rate</string>

@ -337,6 +337,20 @@
<!-- Preference for notifications -->
<string name="preferences_notifications">Notifications</string>
<!-- Add-on Preferences -->
<!-- Preference to customize the configured AMO (addons.mozilla.org) collection -->
<string name="preferences_customize_amo_collection">Custom Add-on collection</string>
<!-- Button caption to confirm the add-on collection configuration -->
<string name="customize_addon_collection_ok">OK</string>
<!-- Button caption to abort the add-on collection configuration -->
<string name="customize_addon_collection_cancel">Cancel</string>
<!-- Hint displayed on input field for custom collection name -->
<string name="customize_addon_collection_hint">Collection name</string>
<!-- Hint displayed on input field for custom collection user ID-->
<string name="customize_addon_collection_user_hint">Collection owner (User ID)</string>
<!-- Toast shown after confirming the custom add-on collection configuration -->
<string name="toast_customize_addon_collection_done">Add-on collection modified. Quitting the application to apply changes…</string>
<!-- Account Preferences -->
<!-- Preference for triggering sync -->
<string name="preferences_sync_now">Sync now</string>

@ -136,6 +136,11 @@
android:key="@string/pref_key_addons"
android:title="@string/preferences_addons" />
<androidx.preference.Preference
android:icon="@drawable/ic_addons_extensions"
android:key="@string/pref_key_override_amo_collection"
android:title="@string/preferences_customize_amo_collection"/>
<androidx.preference.SwitchPreference
android:defaultValue="false"
android:icon="@drawable/ic_open_in_app"

@ -0,0 +1,76 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings
import androidx.fragment.app.FragmentActivity
import androidx.preference.Preference
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.utils.Settings
import org.robolectric.Robolectric
@RunWith(FenixRobolectricTestRunner::class)
class SettingsFragmentTest {
@Test
fun `Add-on collection override pref is visible if debug menu active`() {
val settingsFragment = SettingsFragment()
val activity = Robolectric.buildActivity(FragmentActivity::class.java).create().get()
activity.supportFragmentManager.beginTransaction()
.add(settingsFragment, "test")
.commitNow()
val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>(
settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection)
)
settingsFragment.setupAmoCollectionOverridePreference(mockk(relaxed = true))
assertNotNull(preferenceAmoCollectionOverride)
assertFalse(preferenceAmoCollectionOverride!!.isVisible)
val settings: Settings = mockk(relaxed = true)
every { settings.showSecretDebugMenuThisSession } returns true
settingsFragment.setupAmoCollectionOverridePreference(settings)
assertTrue(preferenceAmoCollectionOverride.isVisible)
}
@Test
fun `Add-on collection override pref is visible if already configured`() {
val settingsFragment = SettingsFragment()
val activity = Robolectric.buildActivity(FragmentActivity::class.java).create().get()
activity.supportFragmentManager.beginTransaction()
.add(settingsFragment, "test")
.commitNow()
val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>(
settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection)
)
settingsFragment.setupAmoCollectionOverridePreference(mockk(relaxed = true))
assertNotNull(preferenceAmoCollectionOverride)
assertFalse(preferenceAmoCollectionOverride!!.isVisible)
val settings: Settings = mockk(relaxed = true)
every { settings.showSecretDebugMenuThisSession } returns false
every { settings.amoCollectionOverrideConfigured() } returns false
settingsFragment.setupAmoCollectionOverridePreference(settings)
assertFalse(preferenceAmoCollectionOverride.isVisible)
every { settings.amoCollectionOverrideConfigured() } returns true
settingsFragment.setupAmoCollectionOverridePreference(settings)
assertTrue(preferenceAmoCollectionOverride.isVisible)
}
}

@ -576,4 +576,34 @@ class SettingsTest {
settings.getSitePermissionsCustomSettingsRules()
)
}
@Test
fun overrideAmoCollection() {
// When just created
// Then
assertEquals("", settings.overrideAmoCollection)
assertFalse(settings.amoCollectionOverrideConfigured())
// When
settings.overrideAmoCollection = "testCollection"
// Then
assertEquals("testCollection", settings.overrideAmoCollection)
assertTrue(settings.amoCollectionOverrideConfigured())
}
@Test
fun overrideAmoUser() {
// When just created
// Then
assertEquals("", settings.overrideAmoUser)
assertFalse(settings.amoCollectionOverrideConfigured())
// When
settings.overrideAmoUser = "testAmoUser"
// Then
assertEquals("testAmoUser", settings.overrideAmoUser)
assertTrue(settings.amoCollectionOverrideConfigured())
}
}

Loading…
Cancel
Save