mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] For https://github.com/mozilla-mobile/fenix/issues/12801 - Extra debug menu trigger, disable if already triggered
This commit is contained in:
parent
1df7dce5d0
commit
fb7c801b38
@ -10,13 +10,11 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.content.pm.PackageInfoCompat
|
import androidx.core.content.pm.PackageInfoCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
||||||
import kotlinx.android.synthetic.main.fragment_about.*
|
import kotlinx.android.synthetic.main.fragment_about.*
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.BuildConfig
|
import org.mozilla.fenix.BuildConfig
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
@ -39,10 +37,9 @@ import org.mozilla.geckoview.BuildConfig as GeckoViewBuildConfig
|
|||||||
* Displays the logo and information about the app, including library versions.
|
* Displays the logo and information about the app, including library versions.
|
||||||
*/
|
*/
|
||||||
class AboutFragment : Fragment(), AboutPageListener {
|
class AboutFragment : Fragment(), AboutPageListener {
|
||||||
|
|
||||||
private lateinit var appName: String
|
private lateinit var appName: String
|
||||||
private val aboutPageAdapter: AboutPageAdapter = AboutPageAdapter(this)
|
private val aboutPageAdapter: AboutPageAdapter = AboutPageAdapter(this)
|
||||||
private var secretDebugMenuClicks = 0
|
|
||||||
private var lastDebugMenuToast: Toast? = null
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@ -56,15 +53,7 @@ class AboutFragment : Fragment(), AboutPageListener {
|
|||||||
return rootView
|
return rootView
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
secretDebugMenuClicks = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
about_list.run {
|
about_list.run {
|
||||||
adapter = aboutPageAdapter
|
adapter = aboutPageAdapter
|
||||||
addItemDecoration(
|
addItemDecoration(
|
||||||
@ -75,33 +64,10 @@ class AboutFragment : Fragment(), AboutPageListener {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5 taps on the logo activate the "secret" debug menu.
|
lifecycle.addObserver(SecretDebugMenuTrigger(
|
||||||
wordmark.setOnClickListener {
|
logoView = wordmark,
|
||||||
// Because the user will mostly likely tap the logo in rapid succession,
|
settings = view.context.settings()
|
||||||
// we ensure only 1 toast is shown at any given time.
|
))
|
||||||
lastDebugMenuToast?.let { toast -> toast.cancel() }
|
|
||||||
secretDebugMenuClicks += 1
|
|
||||||
when (secretDebugMenuClicks) {
|
|
||||||
in 2 until SECRET_DEBUG_MENU_CLICKS -> {
|
|
||||||
val clicksLeft = SECRET_DEBUG_MENU_CLICKS - secretDebugMenuClicks
|
|
||||||
val toast = Toast.makeText(
|
|
||||||
context,
|
|
||||||
getString(R.string.about_debug_menu_toast_progress, clicksLeft),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
|
||||||
toast.show()
|
|
||||||
lastDebugMenuToast = toast
|
|
||||||
}
|
|
||||||
SECRET_DEBUG_MENU_CLICKS -> {
|
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
getString(R.string.about_debug_menu_toast_done),
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
requireContext().settings().showSecretDebugMenuThisSession = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
populateAboutHeader()
|
populateAboutHeader()
|
||||||
aboutPageAdapter.submitList(populateAboutList())
|
aboutPageAdapter.submitList(populateAboutList())
|
||||||
@ -233,7 +199,5 @@ class AboutFragment : Fragment(), AboutPageListener {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ABOUT_LICENSE_URL = "about:license"
|
private const val ABOUT_LICENSE_URL = "about:license"
|
||||||
// Number of clicks on the app logo to enable the "secret" debug menu.
|
|
||||||
private const val SECRET_DEBUG_MENU_CLICKS = 5
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
/* 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.settings.about
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleObserver
|
||||||
|
import androidx.lifecycle.OnLifecycleEvent
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the "secret" debug menu when logoView is tapped 5 times.
|
||||||
|
*/
|
||||||
|
class SecretDebugMenuTrigger(
|
||||||
|
logoView: View,
|
||||||
|
private val settings: Settings
|
||||||
|
) : View.OnClickListener, LifecycleObserver {
|
||||||
|
|
||||||
|
private var secretDebugMenuClicks = 0
|
||||||
|
private var lastDebugMenuToast: Toast? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (!settings.showSecretDebugMenuThisSession) {
|
||||||
|
logoView.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the [secretDebugMenuClicks] counter.
|
||||||
|
*/
|
||||||
|
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||||
|
fun clearClickCounter() {
|
||||||
|
secretDebugMenuClicks = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
// Because the user will mostly likely tap the logo in rapid succession,
|
||||||
|
// we ensure only 1 toast is shown at any given time.
|
||||||
|
lastDebugMenuToast?.cancel()
|
||||||
|
secretDebugMenuClicks += 1
|
||||||
|
when (secretDebugMenuClicks) {
|
||||||
|
in 2 until SECRET_DEBUG_MENU_CLICKS -> {
|
||||||
|
val clicksLeft = SECRET_DEBUG_MENU_CLICKS - secretDebugMenuClicks
|
||||||
|
val toast = Toast.makeText(
|
||||||
|
v.context,
|
||||||
|
v.context.getString(R.string.about_debug_menu_toast_progress, clicksLeft),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
toast.show()
|
||||||
|
lastDebugMenuToast = toast
|
||||||
|
}
|
||||||
|
SECRET_DEBUG_MENU_CLICKS -> {
|
||||||
|
Toast.makeText(
|
||||||
|
v.context,
|
||||||
|
R.string.about_debug_menu_toast_done,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
settings.showSecretDebugMenuThisSession = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// Number of clicks on the app logo to enable the "secret" debug menu.
|
||||||
|
private const val SECRET_DEBUG_MENU_CLICKS = 5
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
/* 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.settings.about
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import io.mockk.CapturingSlot
|
||||||
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.impl.annotations.MockK
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.slot
|
||||||
|
import io.mockk.unmockkStatic
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
class SecretDebugMenuTriggerTest {
|
||||||
|
|
||||||
|
@MockK private lateinit var logoView: View
|
||||||
|
@MockK private lateinit var context: Context
|
||||||
|
@MockK private lateinit var settings: Settings
|
||||||
|
@MockK(relaxUnitFun = true) private lateinit var toast: Toast
|
||||||
|
private lateinit var clickListener: CapturingSlot<View.OnClickListener>
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
MockKAnnotations.init(this)
|
||||||
|
mockkStatic(Toast::class)
|
||||||
|
clickListener = slot()
|
||||||
|
|
||||||
|
every { logoView.setOnClickListener(capture(clickListener)) } just Runs
|
||||||
|
every { logoView.context } returns context
|
||||||
|
every {
|
||||||
|
context.getString(R.string.about_debug_menu_toast_progress, any())
|
||||||
|
} returns "Debug menu: x click(s) left to enable"
|
||||||
|
every { settings.showSecretDebugMenuThisSession } returns false
|
||||||
|
every { settings.showSecretDebugMenuThisSession = any() } just Runs
|
||||||
|
every { Toast.makeText(context, any<Int>(), any()) } returns toast
|
||||||
|
every { Toast.makeText(context, any<String>(), any()) } returns toast
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun teardown() {
|
||||||
|
unmockkStatic(Toast::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toast is not displayed on first click`() {
|
||||||
|
SecretDebugMenuTrigger(logoView, settings)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
|
||||||
|
verify(inverse = true) { Toast.makeText(context, any<String>(), any()) }
|
||||||
|
verify(inverse = true) { toast.show() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toast is displayed on second click`() {
|
||||||
|
SecretDebugMenuTrigger(logoView, settings)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
|
||||||
|
verify { context.getString(R.string.about_debug_menu_toast_progress, 3) }
|
||||||
|
verify { Toast.makeText(context, any<String>(), Toast.LENGTH_SHORT) }
|
||||||
|
verify { toast.show() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clearClickCounter resets counter`() {
|
||||||
|
val trigger = SecretDebugMenuTrigger(logoView, settings)
|
||||||
|
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
trigger.clearClickCounter()
|
||||||
|
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
|
||||||
|
verify(inverse = true) { Toast.makeText(context, any<String>(), any()) }
|
||||||
|
verify(inverse = true) { toast.show() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `toast is displayed on fifth click`() {
|
||||||
|
SecretDebugMenuTrigger(logoView, settings)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
clickListener.captured.onClick(logoView)
|
||||||
|
|
||||||
|
verify { Toast.makeText(
|
||||||
|
context,
|
||||||
|
R.string.about_debug_menu_toast_done,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
) }
|
||||||
|
verify { toast.show() }
|
||||||
|
verify { settings.showSecretDebugMenuThisSession = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `don't register click listener if menu is already shown`() {
|
||||||
|
every { settings.showSecretDebugMenuThisSession } returns true
|
||||||
|
SecretDebugMenuTrigger(logoView, settings)
|
||||||
|
|
||||||
|
verify(inverse = true) { logoView.setOnClickListener(any()) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user