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"