diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt index 9077cd18f936..163211dcc705 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt @@ -42,4 +42,5 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromDownloadLanguagesPreferenceFragment(R.id.downloadLanguagesPreferenceFragment), FromMenuDialogFragment(R.id.menuDialogFragment), FromWebCompatReporterFragment(R.id.webCompatReporterFragment), + FromGleanDebugToolsFragment(R.id.gleanDebugToolsFragment), } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/gleandebugtools/GleanDebugToolsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/gleandebugtools/GleanDebugToolsFragment.kt new file mode 100644 index 000000000000..16fd7b1ca9d9 --- /dev/null +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/gleandebugtools/GleanDebugToolsFragment.kt @@ -0,0 +1,101 @@ +/* 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.debugsettings.gleandebugtools + +import android.annotation.SuppressLint +import android.content.Intent +import android.net.Uri +import android.widget.Toast +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.navigation.fragment.findNavController +import mozilla.telemetry.glean.Glean +import org.mozilla.fenix.R +import org.mozilla.fenix.components.lazyStore +import org.mozilla.fenix.compose.ComposeFragment +import org.mozilla.fenix.debugsettings.gleandebugtools.ui.GleanDebugToolsScreen +import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.theme.FirefoxTheme + +/** + * [ComposeFragment] for displaying the Glean Debug Tools in the about:glean page. + */ +class GleanDebugToolsFragment : ComposeFragment() { + + private val store by lazyStore { + GleanDebugToolsStore( + initialState = GleanDebugToolsState( + logPingsToConsoleEnabled = Glean.getLogPings(), + debugViewTag = Glean.getDebugViewTag() ?: "", + ), + middlewares = listOf( + GleanDebugToolsMiddleware( + gleanDebugToolsStorage = DefaultGleanDebugToolsStorage(), + clipboardHandler = requireComponents.clipboardHandler, + openDebugView = { debugViewLink -> + val intent = Intent(Intent.ACTION_VIEW) + intent.data = Uri.parse(debugViewLink) + requireContext().startActivity(intent) + }, + showToast = { pingType -> + val toast = Toast.makeText( + requireContext(), + requireContext().getString( + R.string.glean_debug_tools_send_ping_toast_message, + pingType, + ), + Toast.LENGTH_LONG, + ) + toast.show() + }, + ), + ), + ) + } + + @Composable + @SuppressLint("UnusedMaterialScaffoldPaddingParameter") + override fun UI() { + FirefoxTheme { + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = stringResource(R.string.glean_debug_tools_title), + color = FirefoxTheme.colors.textPrimary, + style = FirefoxTheme.typography.headline6, + ) + }, + navigationIcon = { + val directions = GleanDebugToolsFragmentDirections.actionGlobalBrowser() + IconButton(onClick = { findNavController().navigate(directions) }) { + Icon( + painter = painterResource(R.drawable.mozac_ic_back_24), + contentDescription = stringResource( + R.string.bookmark_navigate_back_button_content_description, + ), + tint = FirefoxTheme.colors.iconPrimary, + ) + } + }, + backgroundColor = FirefoxTheme.colors.layer1, + ) + }, + backgroundColor = FirefoxTheme.colors.layer1, + ) { + GleanDebugToolsScreen( + gleanDebugToolsStore = store, + ) + } + } + } +} diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt index 0b36e5202668..d9058ed81593 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt @@ -34,6 +34,7 @@ import org.mozilla.fenix.addons.AddonsManagementFragmentDirections import org.mozilla.fenix.components.menu.MenuDialogFragmentDirections import org.mozilla.fenix.customtabs.EXTRA_IS_SANDBOX_CUSTOM_TAB import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity +import org.mozilla.fenix.debugsettings.gleandebugtools.GleanDebugToolsFragmentDirections import org.mozilla.fenix.exceptions.trackingprotection.TrackingProtectionExceptionsFragmentDirections import org.mozilla.fenix.home.HomeFragmentDirections import org.mozilla.fenix.library.bookmarks.BookmarkFragmentDirections @@ -285,6 +286,8 @@ private fun getHomeNavDirections( BrowserDirection.FromHistory -> HistoryFragmentDirections.actionGlobalBrowser() + BrowserDirection.FromGleanDebugToolsFragment -> GleanDebugToolsFragmentDirections.actionGlobalBrowser() + BrowserDirection.FromHistoryMetadataGroup -> HistoryMetadataGroupFragmentDirections.actionGlobalBrowser() BrowserDirection.FromTrackingProtectionExceptions -> diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt index 635a76910871..a9256f14e46b 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt @@ -93,6 +93,10 @@ class SearchDialogController( navController.navigateSafe(R.id.searchDialogFragment, directions) store.dispatch(AwesomeBarAction.EngagementFinished(abandoned = false)) } + "about:glean" -> { + val directions = SearchDialogFragmentDirections.actionGleanDebugToolsFragment() + navController.navigate(directions) + } "moz://a" -> openSearchOrUrl( SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.MANIFESTO), ) diff --git a/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml b/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml index e5feee207c32..730ae4ab514c 100644 --- a/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml +++ b/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml @@ -288,6 +288,9 @@ android:defaultValue="@null" app:argType="string" app:nullable="true" /> + + + diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt index dae47fc1813e..901c32d6e166 100644 --- a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt +++ b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt @@ -50,6 +50,7 @@ import org.mozilla.fenix.components.metrics.MetricsUtils import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.FenixGleanTestRule import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGleanDebugToolsFragment import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalAddonsManagementFragment import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalSearchEngineFragment import org.mozilla.fenix.search.toolbar.SearchSelectorMenu @@ -329,6 +330,18 @@ class SearchDialogControllerTest { } } + @Test + fun handleGleanUrlCommitted() { + val url = "about:glean" + val directions = actionGleanDebugToolsFragment() + + createController().handleUrlCommitted(url) + + browserStore.waitUntilIdle() + + verify { navController.navigate(directions) } + } + @Test fun handleMozillaUrlCommitted() { val url = "moz://a"