Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Commit

Permalink
Bug 1815564 - Modify password field and asterisk added
Browse files Browse the repository at this point in the history
  • Loading branch information
gitstart authored and debojyoti452 committed Feb 27, 2023
1 parent 02e8e67 commit c5e95d2
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ import org.mozilla.fenix.onboarding.FenixOnboarding
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.biometric.BiometricPromptFeature
import org.mozilla.fenix.tabstray.ext.toDisplayTitle
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

package org.mozilla.fenix.settings.logins

import android.graphics.Typeface
import android.text.InputType
import android.widget.ImageButton
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import mozilla.components.service.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R
import org.mozilla.fenix.utils.view.AsteriskPasswordTransformationMethod

fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButton) {
val context = passwordText.context
Expand All @@ -23,6 +25,7 @@ fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButt
revealPasswordButton.setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_password_hide),
)
passwordText.transformationMethod = null
revealPasswordButton.contentDescription =
context.getString(R.string.saved_login_hide_password)
} else {
Expand All @@ -31,9 +34,11 @@ fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButt
revealPasswordButton.setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_password_reveal),
)
passwordText.transformationMethod = AsteriskPasswordTransformationMethod()
revealPasswordButton.contentDescription =
context.getString(R.string.saved_login_reveal_password)
}
// We need to reset to take effect
passwordText.text = passwordText.text
passwordText.typeface = Typeface.MONOSPACE
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import org.mozilla.fenix.settings.logins.SavedLogin
import org.mozilla.fenix.settings.logins.controller.SavedLoginsStorageController
import org.mozilla.fenix.settings.logins.createInitialLoginsListState
import org.mozilla.fenix.settings.logins.interactor.AddLoginInteractor
import org.mozilla.fenix.settings.logins.togglePasswordReveal
import org.mozilla.fenix.utils.view.AsteriskPasswordTransformationMethod

/**
* Displays the editable new login information for a single website
Expand Down Expand Up @@ -80,11 +82,9 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
)

initEditableValues()

setUpClickListeners()
setUpTextListeners()
findDuplicate()

consumeFrom(loginsFragmentStore) {
duplicateLogin = loginsFragmentStore.state.duplicateLogin
updateUsernameField()
Expand All @@ -95,17 +95,17 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
binding.hostnameText.text = "".toEditable()
binding.usernameText.text = "".toEditable()
binding.passwordText.text = "".toEditable()

binding.hostnameText.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
binding.usernameText.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS

// TODO: extend PasswordTransformationMethod() to change bullets to asterisks
binding.passwordText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD

binding.passwordText.compoundDrawablePadding =
requireContext().resources
.getDimensionPixelOffset(R.dimen.saved_logins_end_icon_drawable_padding)
binding.passwordText.transformationMethod = AsteriskPasswordTransformationMethod()
// disabling the clear text buttons until text is entered
binding.clearPasswordTextButton.isVisible = false
binding.revealPasswordButton.isVisible = false
}

private fun setUpClickListeners() {
Expand Down Expand Up @@ -135,6 +135,10 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
binding.inputLayoutPassword.hasFocus()
it.isEnabled = false
}

binding.revealPasswordButton.setOnClickListener {
togglePasswordReveal(binding.passwordText, binding.revealPasswordButton)
}
}

private fun setUpTextListeners() {
Expand Down Expand Up @@ -227,12 +231,14 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
when {
p.toString().isEmpty() -> {
binding.clearPasswordTextButton.isVisible = false
binding.revealPasswordButton.isVisible = false
setPasswordError()
}
else -> {
validPassword = true
binding.inputLayoutPassword.error = null
binding.inputLayoutPassword.errorIconDrawable = null
binding.revealPasswordButton.isVisible = true
binding.clearPasswordTextButton.isVisible = true
binding.clearPasswordTextButton.isEnabled = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import org.mozilla.fenix.settings.logins.controller.SavedLoginsStorageController
import org.mozilla.fenix.settings.logins.createInitialLoginsListState
import org.mozilla.fenix.settings.logins.interactor.EditLoginInteractor
import org.mozilla.fenix.settings.logins.togglePasswordReveal
import org.mozilla.fenix.utils.view.AsteriskPasswordTransformationMethod

/**
* Displays the editable saved login information for a single website
Expand Down Expand Up @@ -112,6 +113,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
binding.hostnameText.isFocusable = false
binding.usernameText.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
// TODO: extend PasswordTransformationMethod() to change bullets to asterisks
binding.passwordText.transformationMethod = AsteriskPasswordTransformationMethod()
binding.passwordText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
binding.passwordText.compoundDrawablePadding =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import org.mozilla.fenix.settings.logins.createInitialLoginsListState
import org.mozilla.fenix.settings.logins.interactor.LoginDetailInteractor
import org.mozilla.fenix.settings.logins.togglePasswordReveal
import org.mozilla.fenix.settings.logins.view.LoginDetailsBindingDelegate
import org.mozilla.fenix.utils.view.AsteriskPasswordTransformationMethod

/**
* Displays saved login information for a single website.
Expand Down Expand Up @@ -125,6 +126,7 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail), Menu
}

private fun setUpPasswordReveal() {
binding.passwordText.transformationMethod = AsteriskPasswordTransformationMethod()
binding.passwordText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
binding.revealPasswordButton.increaseTapArea(BUTTON_INCREASE_DPS)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.mozilla.fenix.utils.view

import android.text.method.PasswordTransformationMethod
import android.view.View

/**
* A [PasswordTransformationMethod] that replaces all characters with asterisks.
*/
class AsteriskPasswordTransformationMethod : PasswordTransformationMethod() {
override fun getTransformation(source: CharSequence, view: View): CharSequence {
return PasswordCharSequence(source)
}

private class PasswordCharSequence(private val source: CharSequence) : CharSequence {
override val length: Int
get() = source.length

override fun get(index: Int): Char {
return '*'
}

override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
return source.subSequence(startIndex, endIndex)
}

override fun toString(): String {
return source.toString()
}
}
}
51 changes: 30 additions & 21 deletions fenix/app/src/main/res/layout/fragment_add_login.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputLayoutHostname"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:colorControlHighlight="?attr/textPrimary"
android:colorControlActivated="?attr/textPrimary"
android:textColor="?attr/textPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@id/hostnameHeaderText"
app:layout_constraintStart_toStartOf="@id/hostnameHeaderText"
app:layout_constraintTop_toBottomOf="@id/hostnameHeaderText"
app:helperTextEnabled="true"
app:helperText="@string/add_login_hostname_invalid_text_3"
Expand All @@ -50,7 +50,6 @@
android:id="@+id/hostnameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:textSize="16sp"
android:fontFamily="sans-serif"
android:textStyle="normal"
Expand Down Expand Up @@ -99,21 +98,21 @@
android:textColor="?attr/textPrimary"
android:letterSpacing="0.05"
app:layout_constraintBottom_toTopOf="@id/inputLayoutUsername"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@id/clearUsernameTextButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inputLayoutHostname"
app:layout_constraintVertical_chainStyle="packed" />

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputLayoutUsername"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:colorControlHighlight="?attr/textPrimary"
android:colorControlActivated="?attr/textPrimary"
android:textColor="?attr/textPrimary"
android:contentDescription="@string/saved_login_username_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@id/usernameHeader"
app:layout_constraintStart_toStartOf="@id/usernameHeader"
app:layout_constraintTop_toBottomOf="@id/usernameHeader"
app:layout_constraintVertical_chainStyle="packed"
app:hintEnabled="false">
Expand All @@ -122,7 +121,6 @@
android:id="@+id/usernameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:textSize="16sp"
android:fontFamily="sans-serif"
android:textStyle="normal"
Expand All @@ -146,14 +144,15 @@
<ImageButton
android:id="@+id/clearUsernameTextButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_height="30dp"
android:layout_marginTop="3dp"
android:layout_marginBottom="10dp"
android:background="@null"
android:contentDescription="@string/saved_login_clear_username"
android:visibility="invisible"
app:tint="@color/saved_login_clear_edit_text_tint"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/inputLayoutUsername"
app:layout_constraintBottom_toBottomOf="@+id/inputLayoutUsername"
app:srcCompat="@drawable/mozac_ic_clear" />

<TextView
Expand All @@ -169,31 +168,30 @@
android:text="@string/preferences_passwords_saved_logins_password"
android:textColor="?attr/textPrimary"
app:layout_constraintBottom_toTopOf="@id/inputLayoutPassword"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/clearPasswordTextButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inputLayoutUsername"
app:layout_constraintVertical_chainStyle="packed" />

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputLayoutPassword"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:colorControlActivated="?attr/textPrimary"
android:colorControlHighlight="?attr/textPrimary"
android:contentDescription="@string/saved_login_password_description"
android:paddingBottom="11dp"
android:textColor="?attr/textPrimary"
app:hintEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@id/passwordHeader"
app:layout_constraintStart_toStartOf="@id/passwordHeader"
app:layout_constraintTop_toBottomOf="@id/passwordHeader"
app:layout_constraintVertical_chainStyle="packed">

<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:clickable="true"
android:colorControlActivated="?attr/textPrimary"
android:colorControlHighlight="?attr/textPrimary"
Expand All @@ -214,16 +212,27 @@
tools:ignore="Autofill" />
</com.google.android.material.textfield.TextInputLayout>

<ImageButton
android:id="@+id/revealPasswordButton"
android:layout_width="48dp"
android:layout_height="30dp"
android:layout_marginTop="3dp"
android:background="@null"
android:contentDescription="@string/saved_login_reveal_password"
app:tint="?attr/textPrimary"
app:layout_constraintEnd_toStartOf="@id/clearPasswordTextButton"
app:layout_constraintTop_toTopOf="@id/inputLayoutPassword"
app:srcCompat="@drawable/mozac_ic_password_reveal" />

<ImageButton
android:id="@+id/clearPasswordTextButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_height="30dp"
android:background="@null"
android:contentDescription="@string/saved_logins_clear_password"
android:visibility="invisible"
app:tint="@color/saved_login_clear_edit_text_tint"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/inputLayoutPassword"
app:srcCompat="@drawable/mozac_ic_clear"
app:tint="@color/saved_login_clear_edit_text_tint" />
app:layout_constraintTop_toTopOf="@id/revealPasswordButton"
app:srcCompat="@drawable/mozac_ic_clear" />

</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit c5e95d2

Please sign in to comment.