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.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
||||
import kotlinx.android.synthetic.main.fragment_about.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.BuildConfig
|
||||
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.
|
||||
*/
|
||||
class AboutFragment : Fragment(), AboutPageListener {
|
||||
|
||||
private lateinit var appName: String
|
||||
private val aboutPageAdapter: AboutPageAdapter = AboutPageAdapter(this)
|
||||
private var secretDebugMenuClicks = 0
|
||||
private var lastDebugMenuToast: Toast? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -56,15 +53,7 @@ class AboutFragment : Fragment(), AboutPageListener {
|
||||
return rootView
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
secretDebugMenuClicks = 0
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
about_list.run {
|
||||
adapter = aboutPageAdapter
|
||||
addItemDecoration(
|
||||
@ -75,33 +64,10 @@ class AboutFragment : Fragment(), AboutPageListener {
|
||||
)
|
||||
}
|
||||
|
||||
// 5 taps on the logo activate the "secret" debug menu.
|
||||
wordmark.setOnClickListener {
|
||||
// Because the user will mostly likely tap the logo in rapid succession,
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle.addObserver(SecretDebugMenuTrigger(
|
||||
logoView = wordmark,
|
||||
settings = view.context.settings()
|
||||
))
|
||||
|
||||
populateAboutHeader()
|
||||
aboutPageAdapter.submitList(populateAboutList())
|
||||
@ -233,7 +199,5 @@ class AboutFragment : Fragment(), AboutPageListener {
|
||||
|
||||
companion object {
|
||||
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