[tbb-commits] [Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.5-1] fixup! Add Tor integration and UI
Dan Ballard (@dan)
git at gitlab.torproject.org
Wed Apr 17 01:00:20 UTC 2024
Dan Ballard pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android
Commits:
2095a229 by clairehurst at 2024-04-17T00:27:30+00:00
fixup! Add Tor integration and UI
- - - - -
4 changed files:
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsComposeFragment.kt
- − fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsFragment.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsViewModel.kt
- fenix/app/src/main/res/navigation/nav_graph.xml
Changes:
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsComposeFragment.kt
=====================================
@@ -0,0 +1,82 @@
+/* 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.tor
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.text.selection.DisableSelection
+import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.unit.dp
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import mozilla.components.ui.colors.PhotonColors
+
+class TorLogsComposeFragment : Fragment() {
+ private val viewModel: TorLogsViewModel by viewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ return ComposeView(requireContext()).apply {
+ setContent {
+ SelectionContainer {
+ Column(
+ // Column instead of LazyColumn so that you can select all the logs, and not just one "screen" at a time
+ // The logs won't be too big so loading them all instead of just whats visible shouldn't be a big deal
+ modifier = Modifier
+ .fillMaxSize()
+ .verticalScroll(state = rememberScrollState(), reverseScrolling = true),
+ ) {
+ for (log in viewModel.torLogs) {
+ LogRow(log = log)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+ at Composable
+ at Stable
+fun LogRow(log: TorLog, modifier: Modifier = Modifier) {
+ Column(
+ modifier
+ .fillMaxWidth()
+ .padding(
+ start = 16.dp,
+ end = 16.dp,
+ bottom = 16.dp,
+ ),
+ ) {
+ DisableSelection {
+ Text(
+ text = log.timestamp.toString(),
+ color = PhotonColors.LightGrey40,
+ modifier = modifier
+ .padding(bottom = 4.dp),
+ )
+ }
+ Text(
+ text = log.text,
+ color = PhotonColors.LightGrey05,
+ )
+ }
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsFragment.kt deleted
=====================================
@@ -1,81 +0,0 @@
-/* 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.tor
-
-import android.os.Bundle
-import android.text.method.ScrollingMovementMethod
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.Fragment
-import org.mozilla.fenix.R
-import org.mozilla.fenix.components.Components
-import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
-import org.mozilla.fenix.ext.requireComponents
-import org.mozilla.fenix.tor.view.TorBootstrapLoggerViewHolder
-
-class TorLogsFragment : Fragment(), TorLogs {
-
- private var entries = mutableListOf<String>()
- internal var _binding: TorBootstrapLoggerBinding? = null
- private val binding get() = _binding!!
-
- private var _components: Components? = null
- private val components get() = _components!!
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?,
- ): View {
- _binding = TorBootstrapLoggerBinding.inflate(inflater)
- _components = requireComponents
-
- components.torController.registerTorLogListener(this)
-
- val currentEntries = components.torController.logEntries.filter { it.second != null }
- .filter { !(it.second!!.startsWith("Circuit") && it.first == "ON") }
- // Keep synchronized with format in onTorStatusUpdate
- .flatMap { listOf("(${it.first}) '${it.second}'") }
- val entriesLen = currentEntries.size
- val subListOffset =
- if (entriesLen > TorBootstrapLoggerViewHolder.MAX_NEW_ENTRIES) TorBootstrapLoggerViewHolder.MAX_NEW_ENTRIES else entriesLen
- entries =
- currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
- val initLog =
- "---------------" + getString(R.string.tor_initializing_log) + "---------------"
- entries.add(0, initLog)
-
- with(binding.torBootstrapLogEntries) {
- movementMethod = ScrollingMovementMethod()
- text = formatLogEntries(entries)
- }
-
-
- return binding.root
- }
-
- // TODO on destroy unregiuster
-
- private fun formatLogEntries(entries: List<String>) = entries.joinToString("\n")
-
- override fun onLog(type: String?, message: String?) {
- if (message == null || type == null) return
- if (type == "ON" && type.startsWith("Circuit")) return
-
- if (entries.size > TorBootstrapLoggerViewHolder.MAX_LINES) {
- entries = entries.drop(1) as MutableList<String>
- }
- entries.add("($type) '$message'")
-
- binding.torBootstrapLogEntries.text = formatLogEntries(entries)
- }
-
- override fun onStop() {
- super.onStop()
- components.torController.unregisterTorLogListener(this)
- }
-
-}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsViewModel.kt
=====================================
@@ -0,0 +1,88 @@
+/* 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.tor
+
+import android.app.Application
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.os.Build
+import android.widget.Toast
+import androidx.compose.runtime.Stable
+import androidx.lifecycle.AndroidViewModel
+import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.components
+import java.sql.Timestamp
+
+class TorLogsViewModel(application: Application) : AndroidViewModel(application), TorLogs {
+ private val torController = application.components.torController
+ private val clipboardManager =
+ application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+
+ val torLogs: MutableList<TorLog> = mutableListOf(
+ TorLog(
+ "---------------" + application.getString(R.string.tor_initializing_log) + "---------------",
+ ),
+ )
+
+ init {
+ setupClipboardListener()
+ torController.registerTorLogListener(this)
+ val currentEntries = torController.logEntries.filter { it.second != null }
+ .filter { !(it.second!!.startsWith("Circuit") && it.first == "ON") }
+ // Keep synchronized with format in onTorStatusUpdate
+ .flatMap { listOf(TorLog("[${it.first}] ${it.second}")) }
+ torLogs.addAll(currentEntries)
+ }
+
+ override fun onLog(type: String?, message: String?) {
+ if (message == null || type == null) return
+ if (type == "ON" && type.startsWith("Circuit")) return
+
+ torLogs.add(TorLog("[$type] $message"))
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ torController.unregisterTorLogListener(this)
+ }
+
+ private fun setupClipboardListener() {
+ clipboardManager.addPrimaryClipChangedListener {
+ // Only show a toast for Android 12 and lower.
+ // https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
+ Toast.makeText(
+ getApplication<Application>().applicationContext,
+ getApplication<Application>().getString(R.string.toast_copy_link_to_clipboard), // "Copied to clipboard" already translated
+ Toast.LENGTH_SHORT,
+ ).show()
+ }
+ }
+ }
+
+ fun copyAllLogsToClipboard() { // TODO add kebab menu in top right corner which includes option to "Copy all logs"
+ clipboardManager.setPrimaryClip(
+ ClipData.newPlainText(
+ "Copied Text",
+ getAllTorLogs(),
+ ),
+ )
+ }
+
+ private fun getAllTorLogs(): String {
+ var ret = ""
+ for (log in torLogs) {
+ ret += log.text + '\n'
+ }
+ return ret
+ }
+}
+
+ at Stable
+data class TorLog(
+ val text: String,
+ val timestamp: Timestamp = Timestamp(System.currentTimeMillis()),
+)
=====================================
fenix/app/src/main/res/navigation/nav_graph.xml
=====================================
@@ -976,8 +976,7 @@
<fragment
android:id="@+id/torBridgeConfigFragment"
android:name="org.mozilla.fenix.settings.TorBridgeConfigFragment"
- android:label="@string/preferences_tor_network_settings_bridge_config"
- tools:layout="@layout/fragment_tor_bridge_config" />
+ android:label="@string/preferences_tor_network_settings_bridge_config" />
<fragment
android:id="@+id/torBetaConnectionFeaturesFragment"
android:name="org.mozilla.fenix.tor.TorBetaConnectionFeaturesFragment"
@@ -985,9 +984,8 @@
tools:layout="@layout/tor_network_settings_beta_connection_features" />
<fragment
android:id="@+id/torLogsFragment"
- android:name="org.mozilla.fenix.tor.TorLogsFragment"
- android:label="Tor Logs"
- tools:layout="@layout/tor_bootstrap_logger" />
+ android:name="org.mozilla.fenix.tor.TorLogsComposeFragment"
+ android:label="@string/preferences_tor_logs" />
<fragment
android:id="@+id/trackingProtectionFragment"
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/2095a229dde4ebe19313e5ad399ad07fdb360b55
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/2095a229dde4ebe19313e5ad399ad07fdb360b55
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20240417/2e5959cb/attachment-0001.htm>
More information about the tbb-commits
mailing list