|
@@ -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
|
|
@@ -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")
|
|
@@ -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
|
|
@@ -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() {
|
|
@@ -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() {
|
|
@@ -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()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -193,6 +204,7 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
|
|
|
} else if (!changed) {
|
|
|
changed = true
|
|
|
}
|
|
|
+
|
|
|
false
|
|
|
}
|
|
|
}
|
|
@@ -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)
|
|
@@ -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(
|
|
@@ -275,7 +287,7 @@ class PassCodeActivity : AppCompatActivity(), Injectable {
|
|
|
}
|
|
|
|
|
|
private fun checkPassCode(): Boolean {
|
|
|
- val savedPassCodeDigits = preferences?.passCode
|
|
|
+ val savedPassCodeDigits = preferences.passCode
|
|
|
return passCodeDigits.zip(savedPassCodeDigits.orEmpty()) { input, saved ->
|
|
|
input == saved
|
|
|
}.all { it }
|
|
@@ -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
|
|
|
}
|
|
|
|
|
@@ -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 {
|
|
@@ -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
|
|
|
}
|
|
|
}
|