Reduce build warnings (#712)
* Add annotations to and reformat SearchableRepositoryViewModel.kt * Address build warnings other than meaningful deprecations * Deal with warnings in UserPreference.kt
This commit is contained in:
parent
2a6326ec0e
commit
e4aa673537
13 changed files with 44 additions and 21 deletions
|
@ -295,7 +295,7 @@ class PasswordStore : AppCompatActivity() {
|
||||||
searchItem.collapseActionView()
|
searchItem.collapseActionView()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openSettings(view: View?) {
|
fun openSettings(@Suppress("UNUSED_PARAMETER") view: View?) {
|
||||||
val intent: Intent
|
val intent: Intent
|
||||||
try {
|
try {
|
||||||
intent = Intent(this, UserPreference::class.java)
|
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)
|
initRepository(CLONE_REPO_BUTTON)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNewRepository(view: View?) {
|
fun createNewRepository(@Suppress("UNUSED_PARAMETER") view: View?) {
|
||||||
initRepository(NEW_REPO_BUTTON)
|
initRepository(NEW_REPO_BUTTON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ class PasswordStore : AppCompatActivity() {
|
||||||
val intent = Intent(this, PgpActivity::class.java)
|
val intent = Intent(this, PgpActivity::class.java)
|
||||||
intent.putExtra("NAME", item.toString())
|
intent.putExtra("NAME", item.toString())
|
||||||
intent.putExtra("FILE_PATH", item.file.absolutePath)
|
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("REPO_PATH", getRepositoryDirectory(applicationContext).absolutePath)
|
||||||
intent.putExtra("OPERATION", "EDIT")
|
intent.putExtra("OPERATION", "EDIT")
|
||||||
startActivityForResult(intent, REQUEST_CODE_EDIT)
|
startActivityForResult(intent, REQUEST_CODE_EDIT)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.os.Parcelable
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
@ -122,8 +123,7 @@ enum class ListMode {
|
||||||
AllEntries
|
AllEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
|
||||||
@FlowPreview
|
|
||||||
class SearchableRepositoryViewModel(application: Application) : AndroidViewModel(application) {
|
class SearchableRepositoryViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
private var _updateCounter = 0
|
private var _updateCounter = 0
|
||||||
|
@ -141,10 +141,10 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
|
||||||
get() = settings.getBoolean("show_hidden_folders", false)
|
get() = settings.getBoolean("show_hidden_folders", false)
|
||||||
private val defaultSearchMode
|
private val defaultSearchMode
|
||||||
get() = if (settings.getBoolean("filter_recursively", true)) {
|
get() = if (settings.getBoolean("filter_recursively", true)) {
|
||||||
SearchMode.RecursivelyInSubdirectories
|
SearchMode.RecursivelyInSubdirectories
|
||||||
} else {
|
} else {
|
||||||
SearchMode.InCurrentDirectoryOnly
|
SearchMode.InCurrentDirectoryOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
private val typeSortOrder
|
private val typeSortOrder
|
||||||
get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings)
|
get() = PasswordRepository.PasswordSortOrder.getSortOrder(settings)
|
||||||
|
@ -352,6 +352,7 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
fun generateStrictDomainRegex(domain: String): Regex? {
|
fun generateStrictDomainRegex(domain: String): Regex? {
|
||||||
// Valid domains do not contain path separators.
|
// Valid domains do not contain path separators.
|
||||||
if (domain.contains('/'))
|
if (domain.contains('/'))
|
||||||
|
@ -377,7 +378,8 @@ private object PasswordItemDiffCallback : DiffUtil.ItemCallback<PasswordItem>()
|
||||||
override fun areItemsTheSame(oldItem: PasswordItem, newItem: PasswordItem) =
|
override fun areItemsTheSame(oldItem: PasswordItem, newItem: PasswordItem) =
|
||||||
oldItem.file.absolutePath == newItem.file.absolutePath
|
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>(
|
open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>(
|
||||||
|
@ -434,6 +436,7 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>(
|
||||||
|
|
||||||
private val selectedFiles
|
private val selectedFiles
|
||||||
get() = requireSelectionTracker().selection.map { File(it) }
|
get() = requireSelectionTracker().selection.map { File(it) }
|
||||||
|
|
||||||
fun getSelectedItems(context: Context): List<PasswordItem> {
|
fun getSelectedItems(context: Context): List<PasswordItem> {
|
||||||
val root = PasswordRepository.getRepositoryDirectory(context)
|
val root = PasswordRepository.getRepositoryDirectory(context)
|
||||||
return selectedFiles.map { it.toPasswordItem(root) }
|
return selectedFiles.map { it.toPasswordItem(root) }
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package com.zeapo.pwdstore
|
package com.zeapo.pwdstore
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityServiceInfo
|
import android.accessibilityservice.AccessibilityServiceInfo
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
|
@ -386,6 +387,7 @@ class UserPreference : AppCompatActivity() {
|
||||||
MaterialAlertDialogBuilder(callingActivity).run {
|
MaterialAlertDialogBuilder(callingActivity).run {
|
||||||
setTitle(R.string.pref_autofill_enable_title)
|
setTitle(R.string.pref_autofill_enable_title)
|
||||||
if (enableOreoAutofill && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (enableOreoAutofill && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
@SuppressLint("InflateParams")
|
||||||
val layout =
|
val layout =
|
||||||
layoutInflater.inflate(R.layout.oreo_autofill_instructions, null)
|
layoutInflater.inflate(R.layout.oreo_autofill_instructions, null)
|
||||||
val supportedBrowsersTextView =
|
val supportedBrowsersTextView =
|
||||||
|
@ -543,7 +545,7 @@ class UserPreference : AppCompatActivity() {
|
||||||
|
|
||||||
private val isAccessibilityServiceEnabled: Boolean
|
private val isAccessibilityServiceEnabled: Boolean
|
||||||
get() {
|
get() {
|
||||||
val am = getSystemService(AccessibilityManager::class.java)
|
val am = getSystemService(AccessibilityManager::class.java) ?: return false
|
||||||
val runningServices = am
|
val runningServices = am
|
||||||
.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
|
.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
|
||||||
return runningServices
|
return runningServices
|
||||||
|
|
|
@ -47,20 +47,23 @@ class AutofillActivity : AppCompatActivity() {
|
||||||
finish() // go back to the password field app
|
finish() // go back to the password field app
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
REQUEST_CODE_DECRYPT_AND_VERIFY -> if (resultCode == RESULT_OK) {
|
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) {
|
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) {
|
REQUEST_CODE_PICK_MATCH_WITH -> if (resultCode == RESULT_OK) {
|
||||||
|
require(data != null)
|
||||||
// need to not only decrypt the picked password, but also
|
// need to not only decrypt the picked password, but also
|
||||||
// update the "match with" preference
|
// update the "match with" preference
|
||||||
val extras = intent.extras ?: return
|
val extras = intent.extras ?: return
|
||||||
val packageName = extras.getString("packageName")
|
val packageName = extras.getString("packageName")
|
||||||
val isWeb = extras.getBoolean("isWeb")
|
val isWeb = extras.getBoolean("isWeb")
|
||||||
|
|
||||||
val path = data!!.getStringExtra("path")
|
val path = data.getStringExtra("path")
|
||||||
AutofillService.instance?.setPickedPassword(data.getStringExtra("path"))
|
AutofillService.instance?.setPickedPassword(data.getStringExtra("path")!!)
|
||||||
|
|
||||||
val prefs: SharedPreferences
|
val prefs: SharedPreferences
|
||||||
prefs = if (!isWeb) {
|
prefs = if (!isWeb) {
|
||||||
|
|
|
@ -66,7 +66,9 @@ class AutofillFragment : DialogFragment() {
|
||||||
?: "com.android.browser")
|
?: "com.android.browser")
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
builder.setIcon(callingActivity.packageManager.getApplicationIcon(iconPackageName))
|
if (iconPackageName != null) {
|
||||||
|
builder.setIcon(callingActivity.packageManager.getApplicationIcon(iconPackageName))
|
||||||
|
}
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package com.zeapo.pwdstore.autofill.oreo
|
package com.zeapo.pwdstore.autofill.oreo
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.assist.AssistStructure
|
import android.app.assist.AssistStructure
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.IntentSender
|
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 `;`.
|
* returns all of them in sorted order and separated with `;`.
|
||||||
*/
|
*/
|
||||||
fun computeCertificatesHash(context: Context, appPackage: String): String {
|
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 =
|
val signaturesOld =
|
||||||
context.packageManager.getPackageInfo(appPackage, PackageManager.GET_SIGNATURES).signatures
|
context.packageManager.getPackageInfo(appPackage, PackageManager.GET_SIGNATURES).signatures
|
||||||
val stableHashOld = stableHash(signaturesOld.map { it.toByteArray() })
|
val stableHashOld = stableHash(signaturesOld.map { it.toByteArray() })
|
||||||
|
|
|
@ -157,6 +157,9 @@ class AutofillMatcher {
|
||||||
for (prefs in listOf(context.autofillAppMatches, context.autofillWebMatches)) {
|
for (prefs in listOf(context.autofillAppMatches, context.autofillWebMatches)) {
|
||||||
for ((key, value) in prefs.all) {
|
for ((key, value) in prefs.all) {
|
||||||
if (!key.startsWith(PREFERENCE_PREFIX_MATCHES)) continue
|
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>
|
val oldMatches = value as? Set<String>
|
||||||
if (oldMatches == null) {
|
if (oldMatches == null) {
|
||||||
w { "Failed to read matches for $key" }
|
w { "Failed to read matches for $key" }
|
||||||
|
|
|
@ -60,7 +60,7 @@ val autofillStrategy = strategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPassword {
|
currentPassword {
|
||||||
takeSingle { alreadyMatched ->
|
takeSingle { _ ->
|
||||||
hasAutocompleteHintCurrentPassword && isFocused
|
hasAutocompleteHintCurrentPassword && isFocused
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ class AutofillDecryptActivity : Activity(), CoroutineScope {
|
||||||
}
|
}
|
||||||
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
|
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
|
||||||
val pendingIntent: PendingIntent =
|
val pendingIntent: PendingIntent =
|
||||||
result.getParcelableExtra(OpenPgpApi.RESULT_INTENT)
|
result.getParcelableExtra(OpenPgpApi.RESULT_INTENT)!!
|
||||||
try {
|
try {
|
||||||
val intentToResume = withContext(Dispatchers.Main) {
|
val intentToResume = withContext(Dispatchers.Main) {
|
||||||
suspendCoroutine<Intent> { cont ->
|
suspendCoroutine<Intent> { cont ->
|
||||||
|
|
|
@ -101,7 +101,7 @@ class AutofillSaveActivity : Activity() {
|
||||||
putExtras(
|
putExtras(
|
||||||
bundleOf(
|
bundleOf(
|
||||||
"REPO_PATH" to repo.absolutePath,
|
"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",
|
"OPERATION" to "ENCRYPT",
|
||||||
"SUGGESTED_NAME" to intent.getStringExtra(EXTRA_NAME),
|
"SUGGESTED_NAME" to intent.getStringExtra(EXTRA_NAME),
|
||||||
"SUGGESTED_PASS" to intent.getStringExtra(EXTRA_PASSWORD),
|
"SUGGESTED_PASS" to intent.getStringExtra(EXTRA_PASSWORD),
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package com.zeapo.pwdstore.crypto
|
package com.zeapo.pwdstore.crypto
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ClipData
|
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) :
|
private inner class HoldToShowPasswordTransformation constructor(button: Button, private val onToggle: Runnable) :
|
||||||
PasswordTransformationMethod(), View.OnTouchListener {
|
PasswordTransformationMethod(), View.OnTouchListener {
|
||||||
private var shown = false
|
private var shown = false
|
||||||
|
@ -784,7 +786,6 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
||||||
return if (shown) charSequence else super.getTransformation("12345", view)
|
return if (shown) charSequence else super.getTransformation("12345", view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ClickableViewAccessibility")
|
|
||||||
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
|
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
|
||||||
when (motionEvent.action) {
|
when (motionEvent.action) {
|
||||||
MotionEvent.ACTION_DOWN -> {
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
|
|
@ -127,6 +127,7 @@ class PasswordBuilder(ctx: Context) {
|
||||||
CapsType.TitleCase -> {
|
CapsType.TitleCase -> {
|
||||||
s = capitalize(s)
|
s = capitalize(s)
|
||||||
}
|
}
|
||||||
|
CapsType.lowercase, CapsType.As_iS -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
password.append(s)
|
password.append(s)
|
||||||
|
|
|
@ -65,6 +65,7 @@ subprojects {
|
||||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '1.8'
|
||||||
|
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue