diff options
Diffstat (limited to 'app/src/main/java')
12 files changed, 43 insertions, 21 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt index df3c0faa..dc09eefe 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt @@ -295,7 +295,7 @@ class PasswordStore : AppCompatActivity() { searchItem.collapseActionView() } - fun openSettings(view: View?) { + fun openSettings(@Suppress("UNUSED_PARAMETER") view: View?) { val intent: Intent try { intent = Intent(this, UserPreference::class.java) @@ -305,11 +305,11 @@ class PasswordStore : AppCompatActivity() { } } - fun cloneExistingRepository(view: View?) { + fun cloneExistingRepository(@Suppress("UNUSED_PARAMETER") view: View?) { initRepository(CLONE_REPO_BUTTON) } - fun createNewRepository(view: View?) { + fun createNewRepository(@Suppress("UNUSED_PARAMETER") view: View?) { initRepository(NEW_REPO_BUTTON) } @@ -473,7 +473,7 @@ class PasswordStore : AppCompatActivity() { val intent = Intent(this, PgpActivity::class.java) intent.putExtra("NAME", item.toString()) intent.putExtra("FILE_PATH", item.file.absolutePath) - intent.putExtra("PARENT_PATH", item.file.parentFile.absolutePath) + intent.putExtra("PARENT_PATH", item.file.parentFile!!.absolutePath) intent.putExtra("REPO_PATH", getRepositoryDirectory(applicationContext).absolutePath) intent.putExtra("OPERATION", "EDIT") startActivityForResult(intent, REQUEST_CODE_EDIT) diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt index b7f7ee61..31258201 100644 --- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt @@ -10,6 +10,7 @@ import android.os.Parcelable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.VisibleForTesting import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -122,8 +123,7 @@ enum class ListMode { AllEntries } -@ExperimentalCoroutinesApi -@FlowPreview +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) class SearchableRepositoryViewModel(application: Application) : AndroidViewModel(application) { private var _updateCounter = 0 @@ -141,10 +141,10 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel get() = settings.getBoolean("show_hidden_folders", false) private val defaultSearchMode get() = if (settings.getBoolean("filter_recursively", true)) { - SearchMode.RecursivelyInSubdirectories - } else { - SearchMode.InCurrentDirectoryOnly - } + SearchMode.RecursivelyInSubdirectories + } else { + SearchMode.InCurrentDirectoryOnly + } private val typeSortOrder get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings) @@ -352,6 +352,7 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel companion object { + @VisibleForTesting fun generateStrictDomainRegex(domain: String): Regex? { // Valid domains do not contain path separators. if (domain.contains('/')) @@ -377,7 +378,8 @@ private object PasswordItemDiffCallback : DiffUtil.ItemCallback<PasswordItem>() override fun areItemsTheSame(oldItem: PasswordItem, newItem: PasswordItem) = oldItem.file.absolutePath == newItem.file.absolutePath - override fun areContentsTheSame(oldItem: PasswordItem, newItem: PasswordItem) = oldItem == newItem + override fun areContentsTheSame(oldItem: PasswordItem, newItem: PasswordItem) = + oldItem == newItem } open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>( @@ -434,6 +436,7 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>( private val selectedFiles get() = requireSelectionTracker().selection.map { File(it) } + fun getSelectedItems(context: Context): List<PasswordItem> { val root = PasswordRepository.getRepositoryDirectory(context) return selectedFiles.map { it.toPasswordItem(root) } diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt index 30c98396..9dd8f418 100644 --- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt +++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt @@ -5,6 +5,7 @@ package com.zeapo.pwdstore import android.accessibilityservice.AccessibilityServiceInfo +import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.content.pm.ShortcutManager @@ -386,6 +387,7 @@ class UserPreference : AppCompatActivity() { MaterialAlertDialogBuilder(callingActivity).run { setTitle(R.string.pref_autofill_enable_title) if (enableOreoAutofill && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + @SuppressLint("InflateParams") val layout = layoutInflater.inflate(R.layout.oreo_autofill_instructions, null) val supportedBrowsersTextView = @@ -543,7 +545,7 @@ class UserPreference : AppCompatActivity() { private val isAccessibilityServiceEnabled: Boolean get() { - val am = getSystemService(AccessibilityManager::class.java) + val am = getSystemService(AccessibilityManager::class.java) ?: return false val runningServices = am .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC) return runningServices diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.kt index 934c5395..c3186db5 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.kt @@ -47,20 +47,23 @@ class AutofillActivity : AppCompatActivity() { finish() // go back to the password field app when (requestCode) { REQUEST_CODE_DECRYPT_AND_VERIFY -> if (resultCode == RESULT_OK) { - AutofillService.instance?.setResultData(data!!) // report the result to service + require(data != null) + AutofillService.instance?.setResultData(data) // report the result to service } REQUEST_CODE_PICK -> if (resultCode == RESULT_OK) { - AutofillService.instance?.setPickedPassword(data!!.getStringExtra("path")) + require(data != null) + AutofillService.instance?.setPickedPassword(data.getStringExtra("path")!!) } REQUEST_CODE_PICK_MATCH_WITH -> if (resultCode == RESULT_OK) { + require(data != null) // need to not only decrypt the picked password, but also // update the "match with" preference val extras = intent.extras ?: return val packageName = extras.getString("packageName") val isWeb = extras.getBoolean("isWeb") - val path = data!!.getStringExtra("path") - AutofillService.instance?.setPickedPassword(data.getStringExtra("path")) + val path = data.getStringExtra("path") + AutofillService.instance?.setPickedPassword(data.getStringExtra("path")!!) val prefs: SharedPreferences prefs = if (!isWeb) { diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.kt index a958fbe8..a2d82097 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.kt @@ -66,7 +66,9 @@ class AutofillFragment : DialogFragment() { ?: "com.android.browser") } try { - builder.setIcon(callingActivity.packageManager.getApplicationIcon(iconPackageName)) + if (iconPackageName != null) { + builder.setIcon(callingActivity.packageManager.getApplicationIcon(iconPackageName)) + } } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt index 47822e0f..59077ac8 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt @@ -4,6 +4,7 @@ */ package com.zeapo.pwdstore.autofill.oreo +import android.annotation.SuppressLint import android.app.assist.AssistStructure import android.content.Context import android.content.IntentSender @@ -47,6 +48,12 @@ private fun stableHash(array: Collection<ByteArray>): String { * returns all of them in sorted order and separated with `;`. */ fun computeCertificatesHash(context: Context, appPackage: String): String { + // The warning does not apply since 1) we are specifically hashing **all** signatures and 2) it + // no longer applies to Android 4.4+. + // Even though there is a new way to get the certificates as of Android Pie, we need to keep + // hashes comparable between versions and hence default to using the deprecated API. + @SuppressLint("PackageManagerGetSignatures") + @Suppress("DEPRECATION") val signaturesOld = context.packageManager.getPackageInfo(appPackage, PackageManager.GET_SIGNATURES).signatures val stableHashOld = stableHash(signaturesOld.map { it.toByteArray() }) diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillMatcher.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillMatcher.kt index e6e16ef0..d300090c 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillMatcher.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillMatcher.kt @@ -157,6 +157,9 @@ class AutofillMatcher { for (prefs in listOf(context.autofillAppMatches, context.autofillWebMatches)) { for ((key, value) in prefs.all) { if (!key.startsWith(PREFERENCE_PREFIX_MATCHES)) continue + // We know that preferences starting with `PREFERENCE_PREFIX_MATCHES` were + // created with `putStringSet`. + @Suppress("UNCHECKED_CAST") val oldMatches = value as? Set<String> if (oldMatches == null) { w { "Failed to read matches for $key" } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillStrategy.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillStrategy.kt index 07a38862..6f3b4ff5 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillStrategy.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillStrategy.kt @@ -60,7 +60,7 @@ val autofillStrategy = strategy { } } currentPassword { - takeSingle { alreadyMatched -> + takeSingle { _ -> hasAutocompleteHintCurrentPassword && isFocused } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt index 2c44ee42..35b1eee9 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt @@ -188,7 +188,7 @@ class AutofillDecryptActivity : Activity(), CoroutineScope { } OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> { val pendingIntent: PendingIntent = - result.getParcelableExtra(OpenPgpApi.RESULT_INTENT) + result.getParcelableExtra(OpenPgpApi.RESULT_INTENT)!! try { val intentToResume = withContext(Dispatchers.Main) { suspendCoroutine<Intent> { cont -> diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt index 384bcad5..209892a7 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt @@ -101,7 +101,7 @@ class AutofillSaveActivity : Activity() { putExtras( bundleOf( "REPO_PATH" to repo.absolutePath, - "FILE_PATH" to repo.resolve(intent.getStringExtra(EXTRA_FOLDER_NAME)).absolutePath, + "FILE_PATH" to repo.resolve(intent.getStringExtra(EXTRA_FOLDER_NAME)!!).absolutePath, "OPERATION" to "ENCRYPT", "SUGGESTED_NAME" to intent.getStringExtra(EXTRA_NAME), "SUGGESTED_PASS" to intent.getStringExtra(EXTRA_PASSWORD), diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt index d878f0a8..be18472d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt @@ -4,6 +4,7 @@ */ package com.zeapo.pwdstore.crypto +import android.annotation.SuppressLint import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.ClipData @@ -772,6 +773,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { } } + @SuppressLint("ClickableViewAccessibility") private inner class HoldToShowPasswordTransformation constructor(button: Button, private val onToggle: Runnable) : PasswordTransformationMethod(), View.OnTouchListener { private var shown = false @@ -784,7 +786,6 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { return if (shown) charSequence else super.getTransformation("12345", view) } - @Suppress("ClickableViewAccessibility") override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { when (motionEvent.action) { MotionEvent.ACTION_DOWN -> { diff --git a/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/PasswordBuilder.kt b/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/PasswordBuilder.kt index a526490f..be9379dc 100644 --- a/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/PasswordBuilder.kt +++ b/app/src/main/java/com/zeapo/pwdstore/pwgenxkpwd/PasswordBuilder.kt @@ -127,6 +127,7 @@ class PasswordBuilder(ctx: Context) { CapsType.TitleCase -> { s = capitalize(s) } + CapsType.lowercase, CapsType.As_iS -> {} } } password.append(s) |