diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt index 248bc6d5fe..fdcbd7c335 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt @@ -105,7 +105,9 @@ class ProfilerStartDialogFragment : AppCompatDialogFragment() { viewStateObserver: MutableState, startProfiler: (Array, Array) -> Unit ) { - val featureAndThreadsObserver = remember { mutableStateOf("") } + val featureAndThreadsObserver = remember { + mutableStateOf(requireContext().resources.getString(R.string.profiler_filter_firefox)) + } ProfilerDialogueCard { Column(modifier = Modifier.padding(8.dp)) { Text( diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt index cc2dda57fe..fc37a84c53 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt @@ -71,10 +71,6 @@ class ProfilerStopDialogFragment : DialogFragment() { // since the user needs to wait for the profiler data to be ready and we don't want to handle // the process in the background. if (viewStateObserver.value != CardState.WaitForProfilerState) { - profilerViewModel.setProfilerState( - requireContext() - .components.core.engine.profiler!!.isProfilerActive() - ) this@ProfilerStopDialogFragment.dismiss() } } @@ -116,7 +112,8 @@ class ProfilerStopDialogFragment : DialogFragment() { ) { TextButton( onClick = { - displayToastAndDismiss(R.string.profile_stop_dialogue_cancel_save) + requireContext().components.core.engine.profiler?.stopProfiler({}, {}) + dismiss() } ) { Text(stringResource(R.string.profiler_start_cancel)) @@ -151,9 +148,9 @@ class ProfilerStopDialogFragment : DialogFragment() { }, onError = { error -> - error.message?.let { + if (error.message != null) { displayToastAndDismiss(R.string.profiler_error, " error: $error") - }?.let { + } else { displayToastAndDismiss(R.string.profiler_error) } } diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt index faa3e1706e..c81e9b5149 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt @@ -74,14 +74,18 @@ enum class ProfilerSettings(val threads: Array, val features: Array Unit) { @@ -138,7 +142,7 @@ object ProfilerUtils { onUrlFinish: (Int) -> Unit ) { try { - val url = saveProfileUrlToClipboardAndToast(profile, context) + val url = saveProfileUrlToClipboard(profile, context) finishProfileSave(context, url, onUrlFinish) } catch (e: IOException) { onUrlFinish(R.string.profiler_io_error) diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerViewModel.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerViewModel.kt index 87f3b05981..6a8910c607 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/ProfilerViewModel.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerViewModel.kt @@ -4,20 +4,32 @@ package org.mozilla.fenix.perf +import android.app.Application +import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import org.mozilla.fenix.FenixApplication +import org.mozilla.fenix.ext.components /** * [ViewModel] to keep track of the profiler state */ -class ProfilerViewModel : ViewModel() { - var isProfilerActive: MutableLiveData = MutableLiveData() +class ProfilerViewModel(application: Application) : AndroidViewModel(application) { + val isProfilerActive: MutableLiveData = MutableLiveData( + application.components.core.engine.profiler?.isProfilerActive() ?: false + ) /** * @return profiler status */ fun getProfilerState(): LiveData { + // We check here since this can be polled from anywhere in Fenix. + getApplication().components.core.engine.profiler?.let { + check(it.isProfilerActive() == isProfilerActive.value) { + "The Profiler state from Gecko is out of sync with the LiveData profiler state." + } + } return isProfilerActive } diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 23a1654592..45a68c324a 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -419,7 +419,7 @@ class SettingsFragment : PreferenceFragmentCompat() { null } resources.getString(R.string.pref_key_start_profiler) -> { - if (requireContext().components.core.engine.profiler?.isProfilerActive()!!) { + if (profilerViewModel.getProfilerState().value == true) { SettingsFragmentDirections.actionSettingsFragmentToStopProfilerDialog() } else { SettingsFragmentDirections.actionSettingsFragmentToStartProfilerDialog() diff --git a/app/src/main/res/values/static_strings.xml b/app/src/main/res/values/static_strings.xml index 715d9214e1..a3fda09ce5 100644 --- a/app/src/main/res/values/static_strings.xml +++ b/app/src/main/res/values/static_strings.xml @@ -57,6 +57,7 @@ Start Profiler Stop Profiler + Profiler Settings Firefox Profiler is currently running @@ -67,30 +68,21 @@ Preset for investigating audio and video bugs in Firefox Networking Preset for investigating networking bugs in Firefox + Profiler started - Would you like to save your profile as: - URL - The profile will upload automatically with all the information gathered and provide you a link from profiler.firefox.com - File - The file will be saved locally on your android device. To share it, go to profiler.firefox.com on your computer or mobile device + Cancel + Gathering the profile - Waiting for Profiler to start - Saving to URL warning - "Saving to URL could potentially show private information such as " + - "urls and screenshots. If you want to keep these" + - "privates, save your profile as a file instead and head on over to profiler.firefox.com" + - "where you can select what to share and not share." - Save as File - Get Profile URL No information was gathered + + Waiting for Profiler to start + + ⚠️ Warning: Profile Upload + Performance profiles may contain sensitive information such as websites visited and screenshots of them. If you continue, your profile will be uploaded and made accessible to anyone with the link. Do you wish to continue? + Upload profile Something went wrong with the profiler Something went wrong contacting the Profiler server. - Something went wrong writing the profile data to the file - Something went wrong saving the profile - The profile was saved locally - Saving profile to file failed, please try again URL copied to clipboard successfully - Profile save operation canceled diff --git a/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt index a66ea9c91a..1563c0d8a2 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt @@ -42,15 +42,16 @@ class SettingsFragmentTest { @Before fun setup() { + // Mock client for fetching account avatar val client = mockk() every { client.fetch(any()) } throws IOException("test") + every { testContext.components.core.engine.profiler } returns mockk(relaxed = true) every { testContext.components.core.client } returns client every { testContext.components.settings } returns mockk(relaxed = true) every { testContext.components.analytics } returns mockk(relaxed = true) every { testContext.components.backgroundServices } returns mockk(relaxed = true) - mockkObject(Config) every { Config.channel } returns ReleaseChannel.Nightly