Commit f2645d89 authored by Alex Catarineu's avatar Alex Catarineu Committed by Matthew Finkel
Browse files

Modify UI/UX

Bug 40015: Modify Home menu

Bug 40016: Hide unwanted Settings

Bug 40016: Modify Default toolbar menu

Bug 40016: Add Donate settings button

Bug 40016: Move Allow Screenshots under Advanced

Bug 40016: Don't install WebCompat webext

Bug 40016: Don't onboard Search Suggestions

Bug 40094: Do not use MasterPasswordTipProvider in HomeFragment

Bug 40095: Hide "Sign in to sync" in bookmarks

Bug 40031: Hide Mozilla-specific items on About page

Bug 40032: Set usesCleartextTraffic as false

Bug 40063: Do not sort search engines alphabetically

Bug 34378: Port external helper app prompting

With the corresponding android-components patch, this allows all `startActivity`
that may open external apps to be replaced by `TorUtils.startActivityPrompt`.

Bug 34403: Disable Normal mode by default

Bug 40087: Implement a switch for english locale spoofing

Bug 40144: Hide Download Manager

Bug 40141: Hide EME site permission
parent 47deabfc
......@@ -28,7 +28,7 @@
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/NormalTheme"
android:usesCleartextTraffic="true"
android:usesCleartextTraffic="false"
tools:ignore="UnusedAttribute">
<!--
......
......@@ -4,6 +4,7 @@
package org.mozilla.fenix
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
......@@ -47,6 +48,8 @@ import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineView
import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.feature.app.links.RedirectDialogFragment
import mozilla.components.feature.app.links.SimpleRedirectDialogFragment
import mozilla.components.feature.contextmenu.DefaultSelectionActionDelegate
import mozilla.components.feature.privatemode.notification.PrivateNotificationFeature
import mozilla.components.feature.search.BrowserStoreSearchAdapter
......@@ -62,6 +65,7 @@ import mozilla.components.support.ktx.kotlin.isUrl
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
import mozilla.components.support.locale.LocaleAwareAppCompatActivity
import mozilla.components.support.utils.SafeIntent
import mozilla.components.support.utils.TorUtils
import mozilla.components.support.utils.toSafeIntent
import mozilla.components.support.webextensions.WebExtensionPopupFeature
import org.mozilla.fenix.GleanMetrics.Metrics
......@@ -167,6 +171,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
private lateinit var navigationToolbar: Toolbar
private var dialog: RedirectDialogFragment? = null
final override fun onCreate(savedInstanceState: Bundle?): Unit = PerfStartup.homeActivityOnCreate.measureNoInline {
// DO NOT MOVE ANYTHING ABOVE THIS addMarker CALL.
components.core.engine.profiler?.addMarker("Activity.onCreate", "HomeActivity")
......@@ -460,6 +465,26 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
super.recreate()
}
// Copied from mozac AppLinksFeature.kt
internal fun getOrCreateDialog(): RedirectDialogFragment {
val existingDialog = dialog
if (existingDialog != null) {
return existingDialog
}
SimpleRedirectDialogFragment.newInstance().also {
dialog = it
return it
}
}
private fun isAlreadyADialogCreated(): Boolean {
return findPreviousDialogFragment() != null
}
private fun findPreviousDialogFragment(): RedirectDialogFragment? {
return supportFragmentManager.findFragmentByTag(RedirectDialogFragment.FRAGMENT_TAG) as? RedirectDialogFragment
}
/**
* Handles intents received when the activity is open.
*/
......@@ -471,6 +496,26 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
open fun handleNewIntent(intent: Intent) {
val startIntent = intent.getParcelableExtra<PendingIntent>(TorUtils.TORBROWSER_START_ACTIVITY_PROMPT)
if (startIntent != null) {
if (startIntent.creatorPackage == applicationContext.packageName) {
val dialog = getOrCreateDialog()
dialog.onConfirmRedirect = {
@Suppress("EmptyCatchBlock")
try {
startIntent.send()
} catch (error: PendingIntent.CanceledException) {
}
}
dialog.onCancelRedirect = {}
if (!isAlreadyADialogCreated()) {
dialog.showNow(supportFragmentManager, RedirectDialogFragment.FRAGMENT_TAG)
}
}
return
}
// Diagnostic breadcrumb for "Display already aquired" crash:
// https://github.com/mozilla-mobile/android-components/issues/7960
breadcrumb(
......@@ -660,11 +705,17 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
internal fun getModeFromIntentOrLastKnown(intent: Intent?): BrowsingMode {
intent?.toSafeIntent()?.let {
if (it.hasExtra(PRIVATE_BROWSING_MODE)) {
val startPrivateMode = it.getBooleanExtra(PRIVATE_BROWSING_MODE, false)
val startPrivateMode = settings().shouldDisableNormalMode ||
it.getBooleanExtra(PRIVATE_BROWSING_MODE, settings().openLinksInAPrivateTab)
return BrowsingMode.fromBoolean(isPrivate = startPrivateMode)
}
}
return settings().lastKnownMode
return when {
settings().shouldDisableNormalMode -> BrowsingMode.Private
settings().openLinksInAPrivateTab -> BrowsingMode.Private
else -> settings().lastKnownMode
}
}
/**
......
......@@ -441,7 +441,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
shouldForwardToThirdParties = {
PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
context.getPreferenceKey(R.string.pref_key_external_download_manager), false
)
) && false
},
promptsStyling = DownloadsFeature.PromptsStyling(
gravity = Gravity.BOTTOM,
......@@ -944,6 +944,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
hideToolbar()
components.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId)?.let {
// If the most-recent session was a tab in Normal mode, and now Normal mode is disabled,
// then load the Private Mode home screen, instead.
if (!it.content.private && requireContext().settings().shouldDisableNormalMode) {
findNavController().nav(
R.id.browserFragment,
BrowserFragmentDirections.actionGlobalHomeFragment()
)
}
updateThemeForSession(it)
}
}
......
......@@ -110,7 +110,8 @@ class Core(
clearColor = ContextCompat.getColor(
context,
R.color.foundation_normal_theme
)
),
spoofEnglish = context.settings().spoofEnglish
)
GeckoEngine(
......@@ -122,7 +123,6 @@ class Core(
trackingProtectionPolicyFactory.createTrackingProtectionPolicy()
)
).also {
WebCompatFeature.install(it)
/**
* There are some issues around localization to be resolved, as well as questions around
......@@ -130,7 +130,8 @@ class Core(
* disabled in Fenix Release builds for now.
* This is consistent with both Fennec and Firefox Desktop.
*/
if (Config.channel.isNightlyOrDebug || Config.channel.isBeta) {
if (false && (Config.channel.isNightlyOrDebug || Config.channel.isBeta)) {
WebCompatFeature.install(it)
WebCompatReporterFeature.install(it, "fenix")
}
}
......
......@@ -228,36 +228,36 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.AddToTopSites)
}
val addToHomescreen = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_add_to_homescreen),
imageResource = R.drawable.ic_add_to_homescreen,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
}
val syncedTabs = BrowserMenuImageText(
label = context.getString(R.string.synced_tabs),
imageResource = R.drawable.ic_synced_tabs,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
}
val installToHomescreen = BrowserMenuHighlightableItem(
label = context.getString(R.string.browser_menu_install_on_homescreen),
startImageResource = R.drawable.ic_add_to_homescreen,
iconTintColorResource = primaryTextColor(),
highlight = BrowserMenuHighlight.LowPriority(
label = context.getString(R.string.browser_menu_install_on_homescreen),
notificationTint = getColor(context, R.color.whats_new_notification_color)
),
isHighlighted = {
!context.settings().installPwaOpened
}
) {
onItemTapped.invoke(ToolbarMenu.Item.InstallToHomeScreen)
}
//val addToHomescreen = BrowserMenuImageText(
// label = context.getString(R.string.browser_menu_add_to_homescreen),
// imageResource = R.drawable.ic_add_to_homescreen,
// iconTintColorResource = primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
//}
//val syncedTabs = BrowserMenuImageText(
// label = context.getString(R.string.synced_tabs),
// imageResource = R.drawable.ic_synced_tabs,
// iconTintColorResource = primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
//}
//val installToHomescreen = BrowserMenuHighlightableItem(
// label = context.getString(R.string.browser_menu_install_on_homescreen),
// startImageResource = R.drawable.ic_add_to_homescreen,
// iconTintColorResource = primaryTextColor(),
// highlight = BrowserMenuHighlight.LowPriority(
// label = context.getString(R.string.browser_menu_install_on_homescreen),
// notificationTint = getColor(context, R.color.whats_new_notification_color)
// ),
// isHighlighted = {
// !context.settings().installPwaOpened
// }
//) {
// onItemTapped.invoke(ToolbarMenu.Item.InstallToHomeScreen)
//}
val findInPage = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_find_in_page),
......@@ -267,9 +267,9 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.FindInPage)
}
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
)
//val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
// id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
//)
val saveToCollection = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_save_to_collection_2),
......@@ -308,13 +308,13 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.OpenInApp)
}
val historyItem = BrowserMenuImageText(
context.getString(R.string.library_history),
R.drawable.ic_history,
primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.History)
}
//val historyItem = BrowserMenuImageText(
// context.getString(R.string.library_history),
// R.drawable.ic_history,
// primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.History)
//}
val bookmarksItem = BrowserMenuImageText(
context.getString(R.string.library_bookmarks),
......@@ -335,22 +335,20 @@ class DefaultToolbarMenu(
// Predicates that are called once, during screen init
val shouldShowSaveToCollection = (context.asActivity() as? HomeActivity)
?.browsingModeManager?.mode == BrowsingMode.Normal
val shouldDeleteDataOnQuit = context.components.settings
.shouldDeleteBrowsingDataOnQuit
val menuItems = listOfNotNull(
downloadsItem,
historyItem,
// historyItem,
bookmarksItem,
syncedTabs,
// syncedTabs,
settings,
if (shouldDeleteDataOnQuit) deleteDataOnQuit else null,
deleteDataOnQuit,
BrowserMenuDivider(),
reportSiteIssuePlaceholder,
//reportSiteIssuePlaceholder,
findInPage,
addToTopSites,
addToHomescreen.apply { visible = ::canAddToHomescreen },
installToHomescreen.apply { visible = ::canInstall },
// addToHomescreen.apply { visible = ::canAddToHomescreen },
// installToHomescreen.apply { visible = ::canInstall },
if (shouldShowSaveToCollection) saveToCollection else null,
desktopMode,
openInApp.apply { visible = ::shouldShowOpenInApp },
......@@ -383,13 +381,13 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.Bookmarks)
}
val historyItem = BrowserMenuImageText(
context.getString(R.string.library_history),
R.drawable.ic_history,
primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.History)
}
//val historyItem = BrowserMenuImageText(
// context.getString(R.string.library_history),
// R.drawable.ic_history,
// primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.History)
//}
val downloadsItem = BrowserMenuImageText(
context.getString(R.string.library_downloads),
......@@ -407,13 +405,13 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.AddonsManager)
}
val syncedTabs = BrowserMenuImageText(
label = context.getString(R.string.synced_tabs),
imageResource = R.drawable.ic_synced_tabs,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
}
//val syncedTabs = BrowserMenuImageText(
// label = context.getString(R.string.synced_tabs),
// imageResource = R.drawable.ic_synced_tabs,
// iconTintColorResource = primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
//}
val findInPageItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_find_in_page),
......@@ -454,17 +452,17 @@ class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.OpenInApp)
}
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
)
//val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
// id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
//)
val addToHomeScreenItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_add_to_homescreen),
imageResource = R.drawable.ic_add_to_homescreen,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
}
//val addToHomeScreenItem = BrowserMenuImageText(
// label = context.getString(R.string.browser_menu_add_to_homescreen),
// imageResource = R.drawable.ic_add_to_homescreen,
// iconTintColorResource = primaryTextColor()
//) {
// onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
//}
val addToTopSitesItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_add_to_top_sites),
......@@ -505,18 +503,18 @@ class DefaultToolbarMenu(
newTabItem,
BrowserMenuDivider(),
bookmarksItem,
historyItem,
//historyItem,
downloadsItem,
extensionsItem,
syncedTabs,
//syncedTabs,
BrowserMenuDivider(),
findInPageItem,
desktopSiteItem,
customizeReaderView.apply { visible = ::shouldShowReaderViewCustomization },
openInApp.apply { visible = ::shouldShowOpenInApp },
reportSiteIssuePlaceholder,
//reportSiteIssuePlaceholder,
BrowserMenuDivider(),
addToHomeScreenItem.apply { visible = ::canAddToHomescreen },
//addToHomeScreenItem.apply { visible = ::canAddToHomescreen },
addToTopSitesItem,
saveToCollectionItem,
BrowserMenuDivider(),
......
......@@ -33,6 +33,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.core.view.doOnLayout
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
......@@ -100,9 +101,7 @@ import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.tips.FenixTipManager
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.providers.MasterPasswordTipProvider
import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.ext.components
......@@ -121,7 +120,6 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.topsites.DefaultTopSitesView
import org.mozilla.fenix.onboarding.FenixOnboarding
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.SupportUtils.SumoTopic.HELP
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.tor.bootstrap.TorQuickStart
import org.mozilla.fenix.theme.ThemeManager
......@@ -233,17 +231,6 @@ class HomeFragment : Fragment() {
expandedCollections = emptySet(),
mode = currentMode.getCurrentMode(),
topSites = components.core.topSitesStorage.cachedTopSites,
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager(
listOf(
MasterPasswordTipProvider(
requireContext(),
::navToSavedLogins,
::dismissTip
)
)
).getTip()
},
showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome
)
)
......@@ -536,6 +523,8 @@ class HomeFragment : Fragment() {
}
}
privateBrowsingButton.isGone = view.context.settings().shouldDisableNormalMode
consumeFrom(requireComponents.core.store) {
updateTabCounter(it)
}
......@@ -689,17 +678,6 @@ class HomeFragment : Fragment() {
collections = components.core.tabCollectionStorage.cachedTabCollections,
mode = currentMode.getCurrentMode(),
topSites = components.core.topSitesStorage.cachedTopSites,
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager(
listOf(
MasterPasswordTipProvider(
requireContext(),
::navToSavedLogins,
::dismissTip
)
)
).getTip()
},
showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome
)
)
......@@ -953,7 +931,7 @@ class HomeFragment : Fragment() {
HomeMenu.Item.Help -> {
hideOnboardingIfNeeded()
(activity as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = SupportUtils.getSumoURLForTopic(context, HELP),
searchTermOrURL = SupportUtils.getTorHelpPageUrl(),
newTab = true,
from = BrowserDirection.FromHome
)
......
......@@ -121,28 +121,29 @@ class HomeMenu(
// user isn't targeted, then we get still get the same treatment.
// The `let` block is degenerate here, but left here so as to document the form of how experiments
// are implemented here.
val historyIcon = experiments.withExperiment(Experiments.A_A_NIMBUS_VALIDATION) {
when (it) {
ExperimentBranch.A1 -> R.drawable.ic_history
ExperimentBranch.A2 -> R.drawable.ic_history
else -> R.drawable.ic_history
}
}
val historyItem = BrowserMenuImageText(
context.getString(R.string.library_history),
historyIcon,
primaryTextColor
) {
onItemTapped.invoke(Item.History)
}
// val historyIcon = experiments.withExperiment(Experiments.A_A_NIMBUS_VALIDATION) {
// when (it) {
// ExperimentBranch.A1 -> R.drawable.ic_history
// ExperimentBranch.A2 -> R.drawable.ic_history
// else -> R.drawable.ic_history
// }
// }
val addons = BrowserMenuImageText(
context.getString(R.string.browser_menu_add_ons),
R.drawable.ic_addons_extensions,
primaryTextColor
) {
onItemTapped.invoke(Item.AddonsManager)
}
// val historyItem = BrowserMenuImageText(
// context.getString(R.string.library_history),
// historyIcon,
// primaryTextColor
// ) {
// onItemTapped.invoke(Item.History)
// }
// val addons = BrowserMenuImageText(
// context.getString(R.string.browser_menu_add_ons),
// R.drawable.ic_addons_extensions,
// primaryTextColor
// ) {
// onItemTapped.invoke(Item.AddonsManager)
// }
val settingsItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_settings),
......@@ -152,13 +153,13 @@ class HomeMenu(
onItemTapped.invoke(Item.Settings)
}
val syncedTabsItem = BrowserMenuImageText(
context.getString(R.string.library_synced_tabs),
R.drawable.ic_synced_tabs,
primaryTextColor
) {
onItemTapped.invoke(Item.SyncedTabs)
}
// val syncedTabsItem = BrowserMenuImageText(
// context.getString(R.string.library_synced_tabs),
// R.drawable.ic_synced_tabs,
// primaryTextColor
// ) {
// onItemTapped.invoke(Item.SyncedTabs)
// }
val helpItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_help),
......@@ -184,18 +185,18 @@ class HomeMenu(
null
}
val settings = context.components.settings
// val settings = context.components.settings
val menuItems = listOfNotNull(
if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null,
quitItem,
settingsItem,
BrowserMenuDivider(),
syncedTabsItem,
// syncedTabsItem,
bookmarksItem,
historyItem,
// historyItem,
downloadsItem,
BrowserMenuDivider(),
addons,
// addons,
BrowserMenuDivider(),
whatsNewItem,
helpItem,
......
......@@ -48,7 +48,6 @@ import org.mozilla.fenix.ext.bookmarkStorage
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.minus
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setTextColor
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.library.LibraryPageFragment
......@@ -128,16 +127,9 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
@ExperimentalCoroutinesApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val accountManager = requireComponents.backgroundServices.accountManager
consumeFrom(bookmarkStore) {
bookmarkView.update(it)
// Only display the sign-in prompt if we're inside of the virtual "Desktop Bookmarks" node.
// Don't want to pester user too much with it, and if there are lots of bookmarks present,
// it'll just get visually lost. Inside of the "Desktop Bookmarks" node, it'll nicely stand-out,
// since there are always only three other items in there. It's also the right place contextually.
bookmarkView.view.bookmark_folders_sign_in.isVisible =
it.tree?.guid == BookmarkRoot.Root.id && accountManager.authenticatedAccount() == null
bookmarkView.view.bookmark_folders_sign_in.isVisible = false
}
}