Skip to content

Commit

Permalink
Merge pull request #13449 from nextcloud/backport/13414/stable-3.29
Browse files Browse the repository at this point in the history
[stable-3.29] BugFix - Resolve Keyboard Not Showing After Lock and Re-enable Password Entry After Delay
  • Loading branch information
AndyScherzinger authored Aug 26, 2024
2 parents c120615 + ebdec02 commit f8050e5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 53 deletions.
110 changes: 58 additions & 52 deletions app/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.google.android.material.snackbar.Snackbar
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.client.di.Injectable
Expand All @@ -28,7 +29,11 @@ import com.owncloud.android.authentication.PassCodeManager
import com.owncloud.android.databinding.PasscodelockBinding
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.ui.components.PassCodeEditText
import com.owncloud.android.ui.components.showKeyboard
import com.owncloud.android.utils.theme.ViewThemeUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import javax.inject.Inject

@Suppress("TooManyFunctions", "MagicNumber")
Expand All @@ -51,17 +56,14 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
const val PREFERENCE_PASSCODE_D4 = "PrefPinCode4"
}

@JvmField
@Inject
var preferences: AppPreferences? = null
lateinit var preferences: AppPreferences

@JvmField
@Inject
var passCodeManager: PassCodeManager? = null
lateinit var passCodeManager: PassCodeManager

@JvmField
@Inject
var viewThemeUtils: ViewThemeUtils? = null
lateinit var viewThemeUtils: ViewThemeUtils

@get:VisibleForTesting
lateinit var binding: PasscodelockBinding
Expand All @@ -85,8 +87,8 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
}

private fun applyTint() {
viewThemeUtils?.platform?.colorViewBackground(binding.cardViewContent, ColorRole.SURFACE_VARIANT)
viewThemeUtils?.material?.colorMaterialButtonPrimaryBorderless(binding.cancel)
viewThemeUtils.platform.colorViewBackground(binding.cardViewContent, ColorRole.SURFACE_VARIANT)
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(binding.cancel)
}

private fun setupPasscodeEditTexts() {
Expand All @@ -96,10 +98,16 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
passCodeEditTexts[3] = binding.txt3

passCodeEditTexts.forEach {
it?.let { viewThemeUtils?.platform?.colorEditText(it) }
it?.let { editText ->
viewThemeUtils.platform.colorEditText(editText)
}
}

passCodeEditTexts[0]?.requestFocus()

binding.cardViewContent.setOnClickListener {
binding.txt0.showKeyboard()
}
}

private fun setSoftInputMode() {
Expand Down Expand Up @@ -140,14 +148,17 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
}

private fun setCancelButtonEnabled(enabled: Boolean) {
binding.cancel.visibility = if (enabled) {
View.VISIBLE
} else {
View.INVISIBLE
}
binding.cancel.setOnClickListener {
if (enabled) {
finish()
binding.cancel.run {
visibility = if (enabled) {
View.VISIBLE
} else {
View.INVISIBLE
}

setOnClickListener {
if (enabled) {
finish()
}
}
}
}
Expand Down Expand Up @@ -193,6 +204,7 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
} else if (!changed) {
changed = true
}

false
}
}
Expand All @@ -207,24 +219,24 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
private fun processFullPassCode() {
if (ACTION_CHECK == intent.action) {
if (checkPassCode()) {
preferences?.resetPinWrongAttempts()
preferences.resetPinWrongAttempts()

// / pass code accepted in request, user is allowed to access the app
passCodeManager?.updateLockTimestamp()
hideSoftKeyboard()
passCodeManager.updateLockTimestamp()
hideKeyboard()
finish()
} else {
preferences?.increasePinWrongAttempts()
preferences.increasePinWrongAttempts()
showErrorAndRestart(R.string.pass_code_wrong, R.string.pass_code_enter_pass_code, View.INVISIBLE)
}
} else if (ACTION_CHECK_WITH_RESULT == intent.action) {
if (checkPassCode()) {
passCodeManager?.updateLockTimestamp()
passCodeManager.updateLockTimestamp()

val resultIntent = Intent()
resultIntent.putExtra(KEY_CHECK_RESULT, true)
setResult(RESULT_OK, resultIntent)
hideSoftKeyboard()
hideKeyboard()
finish()
} else {
showErrorAndRestart(R.string.pass_code_wrong, R.string.pass_code_enter_pass_code, View.INVISIBLE)
Expand All @@ -246,7 +258,7 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
}
}

private fun hideSoftKeyboard() {
private fun hideKeyboard() {
currentFocus?.let {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(
Expand Down Expand Up @@ -320,14 +332,14 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
passCodeDigits[0] + passCodeDigits[1] + passCodeDigits[2] + passCodeDigits[3]
)
setResult(RESULT_OK, resultIntent)
passCodeManager?.updateLockTimestamp()
passCodeManager.updateLockTimestamp()
finish()
}

private fun showDelay() {
val delay = preferences?.pinBruteForceDelay() ?: 0
val delayValue = preferences.pinBruteForceDelay()

if (delay <= 0) {
if (delayValue <= 0) {
return
}

Expand All @@ -338,29 +350,28 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
binding.txt2.isEnabled = false
binding.txt3.isEnabled = false

Thread(object : Runnable {
override fun run() {
try {
Thread.sleep(delay * 1000L)

runOnUiThread {
binding.explanation.visibility = View.INVISIBLE
binding.txt0.isEnabled = true
binding.txt1.isEnabled = true
binding.txt2.isEnabled = true
binding.txt3.isEnabled = true
}
} catch (e: InterruptedException) {
Log_OC.e(this, "Could not delay password input prompt")
}
lifecycleScope.launch(Dispatchers.IO) {
delay(delayValue * 1000L)

launch(Dispatchers.Main) {
binding.explanation.visibility = View.INVISIBLE
binding.txt0.isEnabled = true
binding.txt1.isEnabled = true
binding.txt2.isEnabled = true
binding.txt3.isEnabled = true

binding.txt0.requestFocus()
binding.txt0.showKeyboard()
}
}).start()
}
}

public override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(KEY_CONFIRMING_PASSCODE, confirmingPassCode)
outState.putStringArray(KEY_PASSCODE_DIGITS, passCodeDigits)
outState.run {
putBoolean(KEY_CONFIRMING_PASSCODE, confirmingPassCode)
putStringArray(KEY_PASSCODE_DIGITS, passCodeDigits)
}
}

private inner class PassCodeDigitTextWatcher(index: Int, lastOne: Boolean) : TextWatcher {
Expand Down Expand Up @@ -408,12 +419,7 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
}
}

@Suppress("EmptyFunctionBlock")
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}

@Suppress("EmptyFunctionBlock")
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) = Unit
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) = Unit
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.util.AttributeSet
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.widget.AppCompatEditText

@SuppressLint("ClickableViewAccessibility")
Expand All @@ -25,7 +26,10 @@ class PassCodeEditText(context: Context, attrs: AttributeSet?) : AppCompatEditTe
private fun disableFocusChangeViaTap() {
setSelectAllOnFocus(false)
setTextIsSelectable(false)
setOnTouchListener { _: View?, _: MotionEvent? -> true }
setOnTouchListener { _: View?, _: MotionEvent? ->
showKeyboard()
true
}
}

override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean {
Expand All @@ -37,3 +41,8 @@ class PassCodeEditText(context: Context, attrs: AttributeSet?) : AppCompatEditTe
return super.dispatchKeyEvent(event)
}
}

fun PassCodeEditText.showKeyboard() {
val imm = this.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

0 comments on commit f8050e5

Please sign in to comment.