Skip to content

Commit

Permalink
Bug 1885171 - set private keyboard on Javascript prompts in private b…
Browse files Browse the repository at this point in the history
…rowsing r=android-reviewers,boek

Differential Revision: https://phabricator.services.mozilla.com/D208135
  • Loading branch information
Titouan Thibaud committed May 2, 2024
1 parent 68e2608 commit 386c7f1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.selector.findTabOrCustomTab
import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.prompt.Choice
Expand Down Expand Up @@ -883,6 +884,7 @@ class PromptFeature private constructor(
inputLabel,
inputValue,
promptAbuserDetector.areDialogsBeingAbused(),
store.state.selectedTab?.content?.private == true,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.inputmethod.EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING
import mozilla.components.feature.prompts.R
import mozilla.components.ui.widgets.withCenterAlignedButtons

private const val KEY_USER_EDIT_TEXT = "KEY_USER_EDIT_TEXT"
private const val KEY_LABEL_INPUT = "KEY_LABEL_INPUT"
private const val KEY_DEFAULT_INPUT_VALUE = "KEY_DEFAULT_INPUT_VALUE"
private const val KEY_PRIVATE = "KEY_PRIVATE"

/**
* [androidx.fragment.app.DialogFragment] implementation to display a
Expand All @@ -38,6 +41,11 @@ internal class TextPromptDialogFragment : AbstractPromptTextDialogFragment(), Te
*/
internal val labelInput: String? by lazy { safeArguments.getString(KEY_LABEL_INPUT) }

/**
* Tells if the Dialog is shown from private browsing
*/
internal val private: Boolean? by lazy { safeArguments.getBoolean(KEY_PRIVATE) }

private var userSelectionEditText: String
get() = safeArguments.getString(KEY_USER_EDIT_TEXT, defaultInputValue)
set(value) {
Expand Down Expand Up @@ -73,6 +81,7 @@ internal class TextPromptDialogFragment : AbstractPromptTextDialogFragment(), Te
label.text = labelInput
editText.setText(defaultInputValue)
editText.addTextChangedListener(this)
editText.imeOptions = if (private == true) IME_FLAG_NO_PERSONALIZED_LEARNING else IME_NULL

addCheckBoxIfNeeded(view)

Expand Down Expand Up @@ -100,7 +109,9 @@ internal class TextPromptDialogFragment : AbstractPromptTextDialogFragment(), Te
* @param hasShownManyDialogs tells if this [sessionId] has shown many dialogs
* in a short period of time, if is true a checkbox will be part of the dialog, for the user
* to choose if wants to prevent this [sessionId] continuing showing dialogs.
* @param private tells if this dialog is triggered from private browsing
*/
@Suppress("complexity:LongParameterList")
fun newInstance(
sessionId: String,
promptRequestUID: String,
Expand All @@ -109,6 +120,7 @@ internal class TextPromptDialogFragment : AbstractPromptTextDialogFragment(), Te
inputLabel: String,
defaultInputValue: String,
hasShownManyDialogs: Boolean,
private: Boolean,
): TextPromptDialogFragment {
val fragment = TextPromptDialogFragment()
val arguments = fragment.arguments ?: Bundle()
Expand All @@ -121,6 +133,7 @@ internal class TextPromptDialogFragment : AbstractPromptTextDialogFragment(), Te
putString(KEY_LABEL_INPUT, inputLabel)
putString(KEY_DEFAULT_INPUT_VALUE, defaultInputValue)
putBoolean(KEY_MANY_ALERTS, hasShownManyDialogs)
putBoolean(KEY_PRIVATE, private)
}

fragment.arguments = arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ package mozilla.components.feature.prompts.dialog

import android.content.DialogInterface.BUTTON_POSITIVE
import android.os.Looper.getMainLooper
import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.CheckBox
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.isVisible
import androidx.test.ext.junit.runners.AndroidJUnit4
import mozilla.components.feature.prompts.R.id
Expand Down Expand Up @@ -41,7 +43,7 @@ class TextPromptDialogFragmentTest {
@Test
fun `build dialog`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", true),
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", true, false),
)

doReturn(appCompatContext).`when`(fragment).requireContext()
Expand Down Expand Up @@ -73,12 +75,14 @@ class TextPromptDialogFragmentTest {

inputValue.text = "NewValue"
assertEquals(inputValue.text.toString(), "NewValue")

assertEquals(IME_NULL, inputValue.imeOptions)
}

@Test
fun `TextPrompt with hasShownManyDialogs equals false should not have a checkbox`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", false, "title", "label", "defaultValue", false),
TextPromptDialogFragment.newInstance("sessionId", "uid", false, "title", "label", "defaultValue", false, false),
)

doReturn(appCompatContext).`when`(fragment).requireContext()
Expand All @@ -95,7 +99,7 @@ class TextPromptDialogFragmentTest {
@Test
fun `Clicking on positive button notifies the feature`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", false),
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", false, false),
)

fragment.feature = mockFeature
Expand All @@ -115,7 +119,7 @@ class TextPromptDialogFragmentTest {
@Test
fun `After checking no more dialogs checkbox feature onNoMoreDialogsChecked must be called`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", false, "title", "label", "defaultValue", true),
TextPromptDialogFragment.newInstance("sessionId", "uid", false, "title", "label", "defaultValue", true, false),
)

fragment.feature = mockFeature
Expand All @@ -139,7 +143,7 @@ class TextPromptDialogFragmentTest {
@Test
fun `touching outside of the dialog must notify the feature onCancel`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", true),
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", true, false),
)

fragment.feature = mockFeature
Expand All @@ -150,4 +154,19 @@ class TextPromptDialogFragmentTest {

verify(mockFeature).onCancel("sessionId", "uid")
}

@Test
fun `when TextPromptDialogFragment is created in private mode then keyboard is in private mode`() {
val fragment = spy(
TextPromptDialogFragment.newInstance("sessionId", "uid", true, "title", "label", "defaultValue", true, true),
)

fragment.feature = mockFeature
doReturn(appCompatContext).`when`(fragment).requireContext()

val dialog = fragment.onCreateDialog(null).also { it.show() }
val editText = dialog.findViewById<TextView>(id.input_value)

assertEquals(EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING, editText.imeOptions)
}
}

0 comments on commit 386c7f1

Please sign in to comment.