Loading fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +1 −0 Original line number Diff line number Diff line Loading @@ -41,4 +41,5 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromLoginDetailFragment(R.id.loginDetailFragment), FromTabsTray(R.id.tabsTrayFragment), FromRecentlyClosed(R.id.recentlyClosedFragment), FromTorConnectionAssistFragment(R.id.torConnectionAssistFragment) } fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +5 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ import org.mozilla.fenix.tabstray.TabsTrayFragment import org.mozilla.fenix.tabstray.TabsTrayFragmentDirections import org.mozilla.fenix.theme.DefaultThemeManager import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.tor.TorConnectionAssistFragmentDirections import org.mozilla.fenix.tor.TorEvents import org.mozilla.fenix.trackingprotection.TrackingProtectionPanelDialogFragmentDirections import org.mozilla.fenix.utils.BrowsersCache Loading Loading @@ -1085,6 +1086,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn BrowserDirection.FromStudiesFragment -> StudiesFragmentDirections.actionGlobalBrowser( customTabSessionId, ) BrowserDirection.FromTorConnectionAssistFragment, -> TorConnectionAssistFragmentDirections.actionGlobalBrowser( customTabSessionId, ) } /** Loading fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt 0 → 100644 +131 −0 Original line number Diff line number Diff line /* 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.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import kotlinx.coroutines.launch import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentTorConnectionAssistBinding import org.mozilla.fenix.ext.hideToolbar class TorConnectionAssistFragment : Fragment() { private var _binding: FragmentTorConnectionAssistBinding? = null private val binding get() = _binding!! private val viewModel: TorConnectionAssistViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, ): View { _binding = FragmentTorConnectionAssistBinding.inflate( inflater, container, false, ) return binding.root } override fun onResume() { super.onResume() hideToolbar() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.torConnectState.collect { when (it) { TorConnectState.Initial -> showConfiguring() TorConnectState.Configuring -> showConfiguring() TorConnectState.AutoBootstrapping -> showBootstrapping() TorConnectState.Bootstrapping -> showBootstrapping() TorConnectState.Error -> TODO() TorConnectState.Bootstrapped -> openHome() TorConnectState.Disabled -> openHome() } } } } viewModel.progress().observe( viewLifecycleOwner, ) { progress -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { binding.torBootstrapProgressBar.setProgress(progress, true) } else { binding.torBootstrapProgressBar.progress = progress } } viewModel.quickconnectToggle().observe( viewLifecycleOwner ) { binding.quickstartSwitch.isChecked = it } binding.settingsButton.setOnClickListener { viewModel.cancelTorBootstrap() openSettings() } binding.torBootstrapConnectButton.setOnClickListener { viewModel.handleConnect(lifecycleScope = lifecycleScope) } binding.quickstartSwitch.setOnCheckedChangeListener { _, isChecked -> viewModel.handleQuickstartChecked(isChecked) } } private fun showConfiguring() { binding.torBootstrapConnectButton.visibility = View.VISIBLE binding.torBootstrapNetworkSettingsButton.text = getString(R.string.connection_assist_configure_connection_button) binding.torBootstrapNetworkSettingsButton.setOnClickListener { openTorNetworkSettings() } } private fun showBootstrapping() { binding.torBootstrapConnectButton.visibility = View.INVISIBLE binding.torBootstrapNetworkSettingsButton.text = getString(R.string.btn_cancel) binding.torBootstrapNetworkSettingsButton.setOnClickListener { viewModel.cancelTorBootstrap() } } private fun openSettings(preferenceToScrollTo: String? = null) { findNavController().navigate( TorConnectionAssistFragmentDirections .actionTorConnectionAssistFragmentToSettingsFragment(preferenceToScrollTo), ) } private fun openTorNetworkSettings() { findNavController().navigate( TorConnectionAssistFragmentDirections .actionTorConnectionAssistFragmentToTorNetworkSettings(), ) } private fun openHome() { findNavController().navigate(TorConnectionAssistFragmentDirections.actionStartupHome()) } } fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt 0 → 100644 +86 −0 Original line number Diff line number Diff line /* 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.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.mozilla.fenix.ext.components class TorConnectionAssistViewModel( application: Application, ) : AndroidViewModel(application), TorEvents { private val TAG = "torConnectionAssistVM" private val components = getApplication<Application>().components private val _torController: TorControllerGV = components.torController as TorControllerGV private val _torConnectState = MutableStateFlow(TorConnectState.Initial) internal val torConnectState: StateFlow<TorConnectState> = _torConnectState init { _torController.registerTorListener(this) } private val _progress = MutableLiveData(0) fun progress(): LiveData<Int> { return _progress } private val _quickconnectToggle = MutableLiveData(_torController.quickstart) fun quickconnectToggle(): LiveData<Boolean> { return _quickconnectToggle } fun handleConnect( withDebugLogging: Boolean = false, lifecycleScope: LifecycleCoroutineScope? = null, ) { _torController.initiateTorBootstrap( withDebugLogging = withDebugLogging, lifecycleScope = lifecycleScope, ) } fun handleQuickstartChecked(checked: Boolean) { _torController.quickstart = checked } fun cancelTorBootstrap() { _torController.stopTor() _torController.setTorStopped() } override fun onTorConnecting() { Log.d(TAG, "onTorConnecting()") } override fun onTorConnected() { Log.d(TAG, "onTorConnected()") _torController.unregisterTorListener(this) _torConnectState.value = _torController.lastKnownStatus } override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) { Log.d(TAG, "onTorStatusUpdate($entry, $status, $progress)") if (progress != null) { _progress.value = progress.toInt() } _torConnectState.value = _torController.lastKnownStatus } override fun onTorStopped() { Log.d(TAG, "onTorStopped()") _progress.value = 0 _torConnectState.value = _torController.lastKnownStatus } } fenix/app/src/main/java/org/mozilla/fenix/tor/TorController.kt +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ interface TorController: TorEvents { var bridgesEnabled: Boolean var bridgeTransport: TorBridgeTransportConfig var userProvidedBridges: String? var quickstart: Boolean fun start() fun stop() Loading Loading
fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +1 −0 Original line number Diff line number Diff line Loading @@ -41,4 +41,5 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromLoginDetailFragment(R.id.loginDetailFragment), FromTabsTray(R.id.tabsTrayFragment), FromRecentlyClosed(R.id.recentlyClosedFragment), FromTorConnectionAssistFragment(R.id.torConnectionAssistFragment) }
fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +5 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ import org.mozilla.fenix.tabstray.TabsTrayFragment import org.mozilla.fenix.tabstray.TabsTrayFragmentDirections import org.mozilla.fenix.theme.DefaultThemeManager import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.tor.TorConnectionAssistFragmentDirections import org.mozilla.fenix.tor.TorEvents import org.mozilla.fenix.trackingprotection.TrackingProtectionPanelDialogFragmentDirections import org.mozilla.fenix.utils.BrowsersCache Loading Loading @@ -1085,6 +1086,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn BrowserDirection.FromStudiesFragment -> StudiesFragmentDirections.actionGlobalBrowser( customTabSessionId, ) BrowserDirection.FromTorConnectionAssistFragment, -> TorConnectionAssistFragmentDirections.actionGlobalBrowser( customTabSessionId, ) } /** Loading
fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt 0 → 100644 +131 −0 Original line number Diff line number Diff line /* 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.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import kotlinx.coroutines.launch import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentTorConnectionAssistBinding import org.mozilla.fenix.ext.hideToolbar class TorConnectionAssistFragment : Fragment() { private var _binding: FragmentTorConnectionAssistBinding? = null private val binding get() = _binding!! private val viewModel: TorConnectionAssistViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, ): View { _binding = FragmentTorConnectionAssistBinding.inflate( inflater, container, false, ) return binding.root } override fun onResume() { super.onResume() hideToolbar() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.torConnectState.collect { when (it) { TorConnectState.Initial -> showConfiguring() TorConnectState.Configuring -> showConfiguring() TorConnectState.AutoBootstrapping -> showBootstrapping() TorConnectState.Bootstrapping -> showBootstrapping() TorConnectState.Error -> TODO() TorConnectState.Bootstrapped -> openHome() TorConnectState.Disabled -> openHome() } } } } viewModel.progress().observe( viewLifecycleOwner, ) { progress -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { binding.torBootstrapProgressBar.setProgress(progress, true) } else { binding.torBootstrapProgressBar.progress = progress } } viewModel.quickconnectToggle().observe( viewLifecycleOwner ) { binding.quickstartSwitch.isChecked = it } binding.settingsButton.setOnClickListener { viewModel.cancelTorBootstrap() openSettings() } binding.torBootstrapConnectButton.setOnClickListener { viewModel.handleConnect(lifecycleScope = lifecycleScope) } binding.quickstartSwitch.setOnCheckedChangeListener { _, isChecked -> viewModel.handleQuickstartChecked(isChecked) } } private fun showConfiguring() { binding.torBootstrapConnectButton.visibility = View.VISIBLE binding.torBootstrapNetworkSettingsButton.text = getString(R.string.connection_assist_configure_connection_button) binding.torBootstrapNetworkSettingsButton.setOnClickListener { openTorNetworkSettings() } } private fun showBootstrapping() { binding.torBootstrapConnectButton.visibility = View.INVISIBLE binding.torBootstrapNetworkSettingsButton.text = getString(R.string.btn_cancel) binding.torBootstrapNetworkSettingsButton.setOnClickListener { viewModel.cancelTorBootstrap() } } private fun openSettings(preferenceToScrollTo: String? = null) { findNavController().navigate( TorConnectionAssistFragmentDirections .actionTorConnectionAssistFragmentToSettingsFragment(preferenceToScrollTo), ) } private fun openTorNetworkSettings() { findNavController().navigate( TorConnectionAssistFragmentDirections .actionTorConnectionAssistFragmentToTorNetworkSettings(), ) } private fun openHome() { findNavController().navigate(TorConnectionAssistFragmentDirections.actionStartupHome()) } }
fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt 0 → 100644 +86 −0 Original line number Diff line number Diff line /* 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.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.mozilla.fenix.ext.components class TorConnectionAssistViewModel( application: Application, ) : AndroidViewModel(application), TorEvents { private val TAG = "torConnectionAssistVM" private val components = getApplication<Application>().components private val _torController: TorControllerGV = components.torController as TorControllerGV private val _torConnectState = MutableStateFlow(TorConnectState.Initial) internal val torConnectState: StateFlow<TorConnectState> = _torConnectState init { _torController.registerTorListener(this) } private val _progress = MutableLiveData(0) fun progress(): LiveData<Int> { return _progress } private val _quickconnectToggle = MutableLiveData(_torController.quickstart) fun quickconnectToggle(): LiveData<Boolean> { return _quickconnectToggle } fun handleConnect( withDebugLogging: Boolean = false, lifecycleScope: LifecycleCoroutineScope? = null, ) { _torController.initiateTorBootstrap( withDebugLogging = withDebugLogging, lifecycleScope = lifecycleScope, ) } fun handleQuickstartChecked(checked: Boolean) { _torController.quickstart = checked } fun cancelTorBootstrap() { _torController.stopTor() _torController.setTorStopped() } override fun onTorConnecting() { Log.d(TAG, "onTorConnecting()") } override fun onTorConnected() { Log.d(TAG, "onTorConnected()") _torController.unregisterTorListener(this) _torConnectState.value = _torController.lastKnownStatus } override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) { Log.d(TAG, "onTorStatusUpdate($entry, $status, $progress)") if (progress != null) { _progress.value = progress.toInt() } _torConnectState.value = _torController.lastKnownStatus } override fun onTorStopped() { Log.d(TAG, "onTorStopped()") _progress.value = 0 _torConnectState.value = _torController.lastKnownStatus } }
fenix/app/src/main/java/org/mozilla/fenix/tor/TorController.kt +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ interface TorController: TorEvents { var bridgesEnabled: Boolean var bridgeTransport: TorBridgeTransportConfig var userProvidedBridges: String? var quickstart: Boolean fun start() fun stop() Loading