Replace Timber with logcat (#1509)
* Replace Timber with logcat (#1505) * Add extension for asLog which takes a message param Co-authored-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
parent
c4df226cfd
commit
2cef6a5bb4
44 changed files with 247 additions and 196 deletions
|
@ -107,12 +107,11 @@ dependencies {
|
|||
exclude(group = "org.apache.httpcomponents", module = "httpclient")
|
||||
}
|
||||
implementation(libs.thirdparty.kotlinResult)
|
||||
implementation(libs.thirdparty.logcat)
|
||||
implementation(libs.thirdparty.modernAndroidPrefs)
|
||||
implementation(libs.thirdparty.plumber)
|
||||
implementation(libs.thirdparty.sshauth)
|
||||
implementation(libs.thirdparty.sshj)
|
||||
implementation(libs.thirdparty.timber)
|
||||
implementation(libs.thirdparty.timberkt)
|
||||
|
||||
if (isSnapshot()) {
|
||||
implementation(libs.thirdparty.whatthestack)
|
||||
|
|
|
@ -13,8 +13,6 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
|||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
|
||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
|
||||
import com.github.ajalt.timberkt.Timber.DebugTree
|
||||
import com.github.ajalt.timberkt.Timber.plant
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import dev.msfjarvis.aps.injection.context.FilesDirPath
|
||||
import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
|
||||
|
@ -25,6 +23,7 @@ import dev.msfjarvis.aps.util.settings.GitSettings
|
|||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
import dev.msfjarvis.aps.util.settings.runMigrations
|
||||
import javax.inject.Inject
|
||||
import logcat.AndroidLogcatLogger
|
||||
|
||||
@Suppress("Unused")
|
||||
@HiltAndroidApp
|
||||
|
@ -41,7 +40,7 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
|
|||
if (BuildConfig.ENABLE_DEBUG_FEATURES ||
|
||||
prefs.getBoolean(PreferenceKeys.ENABLE_DEBUG_LOGGING, false)
|
||||
) {
|
||||
plant(DebugTree())
|
||||
AndroidLogcatLogger.installOnDebuggableApp(this)
|
||||
StrictMode.setVmPolicy(VmPolicy.Builder().detectAll().penaltyLog().build())
|
||||
StrictMode.setThreadPolicy(ThreadPolicy.Builder().detectAll().penaltyLog().build())
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartIntentSend
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
|
@ -31,6 +29,7 @@ import dev.msfjarvis.aps.util.autofill.AutofillPreferences
|
|||
import dev.msfjarvis.aps.util.autofill.AutofillResponseBuilder
|
||||
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
|
||||
import dev.msfjarvis.aps.util.extensions.OPENPGP_PROVIDER
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
@ -43,6 +42,9 @@ import kotlin.coroutines.suspendCoroutine
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
|
@ -108,21 +110,21 @@ class AutofillDecryptActivity : AppCompatActivity() {
|
|||
val filePath =
|
||||
intent?.getStringExtra(EXTRA_FILE_PATH)
|
||||
?: run {
|
||||
e { "AutofillDecryptActivity started without EXTRA_FILE_PATH" }
|
||||
logcat(ERROR) { "AutofillDecryptActivity started without EXTRA_FILE_PATH" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val clientState =
|
||||
intent?.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE)
|
||||
?: run {
|
||||
e { "AutofillDecryptActivity started without EXTRA_CLIENT_STATE" }
|
||||
logcat(ERROR) { "AutofillDecryptActivity started without EXTRA_CLIENT_STATE" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val isSearchAction = intent?.getBooleanExtra(EXTRA_SEARCH_ACTION, true)!!
|
||||
val action = if (isSearchAction) AutofillAction.Search else AutofillAction.Match
|
||||
directoryStructure = AutofillPreferences.directoryStructure(this)
|
||||
d { action.toString() }
|
||||
logcat { action.toString() }
|
||||
lifecycleScope.launch {
|
||||
val credentials = decryptCredential(File(filePath))
|
||||
if (credentials == null) {
|
||||
|
@ -183,14 +185,14 @@ class AutofillDecryptActivity : AppCompatActivity() {
|
|||
val command = resumeIntent ?: Intent().apply { action = OpenPgpApi.ACTION_DECRYPT_VERIFY }
|
||||
runCatching { file.inputStream() }
|
||||
.onFailure { e ->
|
||||
e(e) { "File to decrypt not found" }
|
||||
logcat(ERROR) { e.asLog("File to decrypt not found") }
|
||||
return null
|
||||
}
|
||||
.onSuccess { encryptedInput ->
|
||||
val decryptedOutput = ByteArrayOutputStream()
|
||||
runCatching { executeOpenPgpApi(command, encryptedInput, decryptedOutput) }
|
||||
.onFailure { e ->
|
||||
e(e) { "OpenPgpApi ACTION_DECRYPT_VERIFY failed" }
|
||||
logcat(ERROR) { e.asLog("OpenPgpApi ACTION_DECRYPT_VERIFY failed") }
|
||||
return null
|
||||
}
|
||||
.onSuccess { result ->
|
||||
|
@ -212,7 +214,7 @@ class AutofillDecryptActivity : AppCompatActivity() {
|
|||
)
|
||||
}
|
||||
.getOrElse { e ->
|
||||
e(e) { "Failed to parse password entry" }
|
||||
logcat(ERROR) { e.asLog("Failed to parse password entry") }
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +234,9 @@ class AutofillDecryptActivity : AppCompatActivity() {
|
|||
decryptCredential(file, intentToResume)
|
||||
}
|
||||
.getOrElse { e ->
|
||||
e(e) { "OpenPgpApi ACTION_DECRYPT_VERIFY failed with user interaction" }
|
||||
logcat(ERROR) {
|
||||
e.asLog("OpenPgpApi ACTION_DECRYPT_VERIFY failed with user interaction")
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
@ -247,14 +251,14 @@ class AutofillDecryptActivity : AppCompatActivity() {
|
|||
)
|
||||
.show()
|
||||
}
|
||||
e {
|
||||
logcat(ERROR) {
|
||||
"OpenPgpApi ACTION_DECRYPT_VERIFY failed (${error.errorId}): ${error.message}"
|
||||
}
|
||||
}
|
||||
null
|
||||
}
|
||||
else -> {
|
||||
e { "Unrecognized OpenPgpApi result: $resultCode" }
|
||||
logcat(ERROR) { "Unrecognized OpenPgpApi result: $resultCode" }
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ import android.view.autofill.AutofillManager
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
|
@ -29,11 +27,15 @@ import dev.msfjarvis.aps.ui.crypto.DecryptActivityV2
|
|||
import dev.msfjarvis.aps.util.autofill.AutofillPreferences
|
||||
import dev.msfjarvis.aps.util.autofill.AutofillResponseBuilder
|
||||
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@AndroidEntryPoint
|
||||
|
@ -80,21 +82,21 @@ class AutofillDecryptActivityV2 : AppCompatActivity() {
|
|||
val filePath =
|
||||
intent?.getStringExtra(EXTRA_FILE_PATH)
|
||||
?: run {
|
||||
e { "AutofillDecryptActivityV2 started without EXTRA_FILE_PATH" }
|
||||
logcat(ERROR) { "AutofillDecryptActivityV2 started without EXTRA_FILE_PATH" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val clientState =
|
||||
intent?.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE)
|
||||
?: run {
|
||||
e { "AutofillDecryptActivityV2 started without EXTRA_CLIENT_STATE" }
|
||||
logcat(ERROR) { "AutofillDecryptActivityV2 started without EXTRA_CLIENT_STATE" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val isSearchAction = intent?.getBooleanExtra(EXTRA_SEARCH_ACTION, true)!!
|
||||
val action = if (isSearchAction) AutofillAction.Search else AutofillAction.Match
|
||||
directoryStructure = AutofillPreferences.directoryStructure(this)
|
||||
d { action.toString() }
|
||||
logcat { action.toString() }
|
||||
lifecycleScope.launch {
|
||||
val credentials = decryptCredential(File(filePath))
|
||||
if (credentials == null) {
|
||||
|
@ -121,7 +123,7 @@ class AutofillDecryptActivityV2 : AppCompatActivity() {
|
|||
private suspend fun decryptCredential(file: File): Credentials? {
|
||||
runCatching { file.inputStream() }
|
||||
.onFailure { e ->
|
||||
e(e) { "File to decrypt not found" }
|
||||
logcat(ERROR) { e.asLog("File to decrypt not found") }
|
||||
return null
|
||||
}
|
||||
.onSuccess { encryptedInput ->
|
||||
|
@ -136,7 +138,7 @@ class AutofillDecryptActivityV2 : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
.onFailure { e ->
|
||||
e(e) { "Decryption failed" }
|
||||
logcat(ERROR) { e.asLog("Decryption failed") }
|
||||
return null
|
||||
}
|
||||
.onSuccess { result ->
|
||||
|
@ -145,7 +147,7 @@ class AutofillDecryptActivityV2 : AppCompatActivity() {
|
|||
AutofillPreferences.credentialsFromStoreEntry(this, file, entry, directoryStructure)
|
||||
}
|
||||
.getOrElse { e ->
|
||||
e(e) { "Failed to parse password entry" }
|
||||
logcat(ERROR) { e.asLog("Failed to parse password entry") }
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import androidx.core.widget.addTextChangedListener
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.FormOrigin
|
||||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.data.password.PasswordItem
|
||||
|
@ -39,6 +38,8 @@ import dev.msfjarvis.aps.util.viewmodel.ListMode
|
|||
import dev.msfjarvis.aps.util.viewmodel.SearchMode
|
||||
import dev.msfjarvis.aps.util.viewmodel.SearchableRepositoryAdapter
|
||||
import dev.msfjarvis.aps.util.viewmodel.SearchableRepositoryViewModel
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
class AutofillFilterView : AppCompatActivity() {
|
||||
|
@ -102,7 +103,7 @@ class AutofillFilterView : AppCompatActivity() {
|
|||
window.attributes = params
|
||||
|
||||
if (intent?.hasExtra(AutofillManager.EXTRA_CLIENT_STATE) != true) {
|
||||
e { "AutofillFilterActivity started without EXTRA_CLIENT_STATE" }
|
||||
logcat(ERROR) { "AutofillFilterActivity started without EXTRA_CLIENT_STATE" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ class AutofillFilterView : AppCompatActivity() {
|
|||
FormOrigin.App(intent!!.getStringExtra(EXTRA_FORM_ORIGIN_APP)!!)
|
||||
}
|
||||
else -> {
|
||||
e {
|
||||
logcat(ERROR) {
|
||||
"AutofillFilterActivity started without EXTRA_FORM_ORIGIN_WEB or EXTRA_FORM_ORIGIN_APP"
|
||||
}
|
||||
finish()
|
||||
|
|
|
@ -17,7 +17,6 @@ import android.text.format.DateUtils
|
|||
import android.view.View
|
||||
import android.view.autofill.AutofillManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.FormOrigin
|
||||
import com.github.androidpasswordstore.autofillparser.computeCertificatesHash
|
||||
import com.github.michaelbull.result.onFailure
|
||||
|
@ -26,7 +25,10 @@ import dev.msfjarvis.aps.R
|
|||
import dev.msfjarvis.aps.databinding.ActivityOreoAutofillPublisherChangedBinding
|
||||
import dev.msfjarvis.aps.util.autofill.AutofillMatcher
|
||||
import dev.msfjarvis.aps.util.autofill.AutofillPublisherChangedException
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||
|
@ -69,7 +71,7 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
|
|||
appPackage =
|
||||
intent.getStringExtra(EXTRA_APP_PACKAGE)
|
||||
?: run {
|
||||
e { "AutofillPublisherChangedActivity started without EXTRA_PACKAGE_NAME" }
|
||||
logcat(ERROR) { "AutofillPublisherChangedActivity started without EXTRA_PACKAGE_NAME" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
@ -117,7 +119,7 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
.onFailure { e ->
|
||||
e(e) { "Failed to retrieve package info for $appPackage" }
|
||||
logcat(ERROR) { e.asLog("Failed to retrieve package info for $appPackage") }
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
import com.github.androidpasswordstore.autofillparser.FormOrigin
|
||||
|
@ -26,6 +25,8 @@ import dev.msfjarvis.aps.util.autofill.AutofillPreferences
|
|||
import dev.msfjarvis.aps.util.autofill.AutofillResponseBuilder
|
||||
import dev.msfjarvis.aps.util.extensions.unsafeLazy
|
||||
import java.io.File
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutofillSaveActivity : AppCompatActivity() {
|
||||
|
@ -131,7 +132,7 @@ class AutofillSaveActivity : AppCompatActivity() {
|
|||
val clientState =
|
||||
intent?.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE)
|
||||
?: run {
|
||||
e { "AutofillDecryptActivity started without EXTRA_CLIENT_STATE" }
|
||||
logcat(ERROR) { "AutofillDecryptActivity started without EXTRA_CLIENT_STATE" }
|
||||
finish()
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ import android.view.WindowManager
|
|||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.github.ajalt.timberkt.Timber.tag
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.ajalt.timberkt.i
|
||||
import com.github.michaelbull.result.getOr
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -29,6 +26,7 @@ import dev.msfjarvis.aps.R
|
|||
import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
|
||||
import dev.msfjarvis.aps.util.FeatureFlags
|
||||
import dev.msfjarvis.aps.util.extensions.OPENPGP_PROVIDER
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.clipboard
|
||||
import dev.msfjarvis.aps.util.extensions.getString
|
||||
import dev.msfjarvis.aps.util.extensions.snackbar
|
||||
|
@ -37,6 +35,9 @@ import dev.msfjarvis.aps.util.services.ClipboardService
|
|||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.LogPriority.INFO
|
||||
import logcat.logcat
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
|
@ -82,7 +83,6 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
|
||||
tag(TAG)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,7 +121,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
|||
* super.
|
||||
*/
|
||||
override fun onError(e: Exception) {
|
||||
e(e) { "Callers must handle their own exceptions" }
|
||||
logcat(ERROR) { e.asLog("Callers must handle their own exceptions") }
|
||||
throw e
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
|||
* @param result The intent returned by OpenKeychain
|
||||
*/
|
||||
fun getUserInteractionRequestIntent(result: Intent): IntentSender {
|
||||
i { "RESULT_CODE_USER_INTERACTION_REQUIRED" }
|
||||
logcat(INFO) { "RESULT_CODE_USER_INTERACTION_REQUIRED" }
|
||||
return result.getParcelableExtra<PendingIntent>(OpenPgpApi.RESULT_INTENT)!!.intentSender
|
||||
}
|
||||
|
||||
|
@ -196,8 +196,8 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
|||
}
|
||||
else -> {
|
||||
snackbar(message = getString(R.string.openpgp_error_unknown, error.message))
|
||||
e { "onError getErrorId: ${error.errorId}" }
|
||||
e { "onError getMessage: ${error.message}" }
|
||||
logcat(ERROR) { "onError getErrorId: ${error.errorId}" }
|
||||
logcat(ERROR) { "onError getMessage: ${error.message}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import android.view.MenuItem
|
|||
import androidx.activity.result.IntentSenderRequest
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
@ -35,6 +34,9 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
|
@ -110,7 +112,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
|
|||
}
|
||||
|
||||
override fun onError(e: Exception) {
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +214,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
|
|||
binding.recyclerView.adapter = adapter
|
||||
adapter.updateItems(items)
|
||||
}
|
||||
.onFailure { e -> e(e) }
|
||||
.onFailure { e -> logcat(ERROR) { e.asLog() } }
|
||||
}
|
||||
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
|
||||
val sender = getUserInteractionRequestIntent(result)
|
||||
|
|
|
@ -10,12 +10,14 @@ import android.os.Bundle
|
|||
import androidx.activity.result.IntentSenderRequest
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpUtils
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
|
@ -43,7 +45,7 @@ class GetKeyIdsActivity : BasePgpActivity() {
|
|||
}
|
||||
|
||||
override fun onError(e: Exception) {
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
}
|
||||
|
||||
/** Get the Key ids from OpenKeychain */
|
||||
|
@ -63,7 +65,7 @@ class GetKeyIdsActivity : BasePgpActivity() {
|
|||
setResult(RESULT_OK, keyResult)
|
||||
finish()
|
||||
}
|
||||
.onFailure { e -> e(e) }
|
||||
.onFailure { e -> logcat(ERROR) { e.asLog() } }
|
||||
}
|
||||
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
|
||||
val sender = getUserInteractionRequestIntent(result)
|
||||
|
|
|
@ -20,7 +20,6 @@ import androidx.core.content.edit
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.onSuccess
|
||||
import com.github.michaelbull.result.runCatching
|
||||
|
@ -39,6 +38,7 @@ import dev.msfjarvis.aps.ui.dialogs.XkPasswordGeneratorDialogFragment
|
|||
import dev.msfjarvis.aps.util.autofill.AutofillPreferences
|
||||
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
|
||||
import dev.msfjarvis.aps.util.crypto.GpgIdentifier
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.base64
|
||||
import dev.msfjarvis.aps.util.extensions.commitChange
|
||||
import dev.msfjarvis.aps.util.extensions.getString
|
||||
|
@ -55,6 +55,9 @@ import javax.inject.Inject
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
|
||||
|
@ -520,7 +523,7 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
|
|||
}
|
||||
.onFailure { e ->
|
||||
if (e is IOException) {
|
||||
e(e) { "Failed to write password file" }
|
||||
logcat(ERROR) { e.asLog("Failed to write password file") }
|
||||
setResult(RESULT_CANCELED)
|
||||
MaterialAlertDialogBuilder(this@PasswordCreationActivity)
|
||||
.setTitle(getString(R.string.password_creation_file_fail_title))
|
||||
|
@ -529,7 +532,7 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
|
|||
.setPositiveButton(android.R.string.ok) { _, _ -> finish() }
|
||||
.show()
|
||||
} else {
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import androidx.core.content.edit
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.onSuccess
|
||||
import com.github.michaelbull.result.runCatching
|
||||
|
@ -35,6 +34,7 @@ import dev.msfjarvis.aps.ui.dialogs.PasswordGeneratorDialogFragment
|
|||
import dev.msfjarvis.aps.ui.dialogs.XkPasswordGeneratorDialogFragment
|
||||
import dev.msfjarvis.aps.util.autofill.AutofillPreferences
|
||||
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.base64
|
||||
import dev.msfjarvis.aps.util.extensions.commitChange
|
||||
import dev.msfjarvis.aps.util.extensions.getString
|
||||
|
@ -49,6 +49,9 @@ import javax.inject.Inject
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PasswordCreationActivityV2 : BasePgpActivity() {
|
||||
|
@ -393,7 +396,7 @@ class PasswordCreationActivityV2 : BasePgpActivity() {
|
|||
}
|
||||
.onFailure { e ->
|
||||
if (e is IOException) {
|
||||
e(e) { "Failed to write password file" }
|
||||
logcat(ERROR) { e.asLog("Failed to write password file") }
|
||||
setResult(RESULT_CANCELED)
|
||||
MaterialAlertDialogBuilder(this@PasswordCreationActivityV2)
|
||||
.setTitle(getString(R.string.password_creation_file_fail_title))
|
||||
|
@ -402,7 +405,7 @@ class PasswordCreationActivityV2 : BasePgpActivity() {
|
|||
.setPositiveButton(android.R.string.ok) { _, _ -> finish() }
|
||||
.show()
|
||||
} else {
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import androidx.core.os.bundleOf
|
|||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.Timber.tag
|
||||
import com.github.michaelbull.result.fold
|
||||
import com.github.michaelbull.result.getOr
|
||||
import com.github.michaelbull.result.runCatching
|
||||
|
@ -24,6 +23,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.databinding.FragmentXkpwgenBinding
|
||||
import dev.msfjarvis.aps.ui.crypto.PasswordCreationActivity
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.getString
|
||||
import dev.msfjarvis.aps.util.pwgenxkpwd.CapsType
|
||||
import dev.msfjarvis.aps.util.pwgenxkpwd.PasswordBuilder
|
||||
|
@ -31,6 +31,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
import reactivecircus.flowbinding.android.widget.afterTextChanges
|
||||
import reactivecircus.flowbinding.android.widget.selectionEvents
|
||||
|
||||
|
@ -119,7 +121,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
|||
success = { binding.xkPasswordText.text = it },
|
||||
failure = { e ->
|
||||
Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show()
|
||||
tag("xkpw").e(e, "failure generating xkpasswd")
|
||||
logcat("xkpw", ERROR) { e.asLog("failure generating xkpasswd") }
|
||||
binding.xkPasswordText.text = FALLBACK_ERROR_PASS
|
||||
},
|
||||
)
|
||||
|
|
|
@ -7,7 +7,6 @@ package dev.msfjarvis.aps.ui.git.base
|
|||
import android.content.SharedPreferences
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.edit
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.michaelbull.result.Err
|
||||
import com.github.michaelbull.result.Result
|
||||
import com.github.michaelbull.result.andThen
|
||||
|
@ -30,6 +29,8 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
|||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import net.schmizz.sshj.common.DisconnectReason
|
||||
import net.schmizz.sshj.common.SSHException
|
||||
import net.schmizz.sshj.transport.TransportException
|
||||
|
@ -89,7 +90,7 @@ abstract class BaseGitActivity : ContinuationContainerActivity() {
|
|||
if (!isExplicitlyUserInitiatedError(error)) {
|
||||
gitPrefs.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
|
||||
sharedPrefs.edit { remove(PreferenceKeys.SSH_OPENKEYSTORE_KEYID) }
|
||||
d(error)
|
||||
logcat { error.asLog() }
|
||||
withContext(Dispatchers.Main) {
|
||||
MaterialAlertDialogBuilder(this@BaseGitActivity).run {
|
||||
setTitle(resources.getString(R.string.jgit_error_dialog_title))
|
||||
|
|
|
@ -12,7 +12,6 @@ import android.util.Patterns
|
|||
import android.view.MenuItem
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.fold
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
import com.github.michaelbull.result.onFailure
|
||||
|
@ -26,6 +25,8 @@ import dev.msfjarvis.aps.ui.git.base.BaseGitActivity
|
|||
import dev.msfjarvis.aps.ui.git.log.GitLogActivity
|
||||
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||
import kotlinx.coroutines.launch
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
import org.eclipse.jgit.lib.Constants
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.lib.RepositoryState
|
||||
|
@ -88,7 +89,7 @@ class GitConfigActivity : BaseGitActivity() {
|
|||
}
|
||||
binding.gitLog.setOnClickListener {
|
||||
runCatching { startActivity(Intent(this, GitLogActivity::class.java)) }.onFailure { ex ->
|
||||
e(ex) { "Failed to start GitLogActivity" }
|
||||
logcat(ERROR) { "Failed to start GitLogActivity\n${ex}" }
|
||||
}
|
||||
}
|
||||
binding.gitAbortRebase.setOnClickListener {
|
||||
|
@ -143,7 +144,7 @@ class GitConfigActivity : BaseGitActivity() {
|
|||
}
|
||||
}
|
||||
.getOrElse { ex ->
|
||||
e(ex) { "Error getting HEAD reference" }
|
||||
logcat(ERROR) { "Error getting HEAD reference\n${ex}" }
|
||||
getString(R.string.git_head_missing)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import androidx.core.os.postDelayed
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.fold
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.runCatching
|
||||
|
@ -34,6 +33,9 @@ import dev.msfjarvis.aps.util.settings.Protocol
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
/**
|
||||
* Activity that encompasses both the initial clone as well as editing the server config for future
|
||||
|
@ -269,7 +271,7 @@ class GitServerConfigActivity : BaseGitActivity() {
|
|||
}
|
||||
}
|
||||
.onFailure { e ->
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
MaterialAlertDialogBuilder(this).setMessage(e.message).show()
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
|
|
|
@ -8,12 +8,13 @@ package dev.msfjarvis.aps.ui.git.log
|
|||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.ajalt.timberkt.e
|
||||
import dev.msfjarvis.aps.databinding.GitLogRowLayoutBinding
|
||||
import dev.msfjarvis.aps.util.git.GitCommit
|
||||
import dev.msfjarvis.aps.util.git.GitLogModel
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
private fun shortHash(hash: String): String {
|
||||
return hash.substring(0 until 8)
|
||||
|
@ -37,7 +38,7 @@ class GitLogAdapter : RecyclerView.Adapter<GitLogAdapter.ViewHolder>() {
|
|||
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
|
||||
val commit = model.get(position)
|
||||
if (commit == null) {
|
||||
e { "There is no git commit for view holder at position $position." }
|
||||
logcat(ERROR) { "There is no git commit for view holder at position $position." }
|
||||
return
|
||||
}
|
||||
viewHolder.bind(commit)
|
||||
|
|
|
@ -13,8 +13,6 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.edit
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -33,6 +31,9 @@ import dev.msfjarvis.aps.util.extensions.viewBinding
|
|||
import dev.msfjarvis.aps.util.settings.PasswordSortOrder
|
||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
import java.io.File
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||
|
||||
|
@ -160,9 +161,9 @@ class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
|||
parentFragmentManager.performTransactionWithBackStack(KeySelectionFragment.newInstance())
|
||||
}
|
||||
.onFailure { e ->
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
if (!localDir.delete()) {
|
||||
d { "Failed to delete local repository: $localDir" }
|
||||
logcat { "Failed to delete local repository: $localDir" }
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
|
|
@ -25,9 +25,6 @@ import androidx.fragment.app.FragmentManager
|
|||
import androidx.fragment.app.commit
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.ajalt.timberkt.i
|
||||
import com.github.michaelbull.result.fold
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import com.github.michaelbull.result.runCatching
|
||||
|
@ -68,6 +65,9 @@ import javax.inject.Inject
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.LogPriority.INFO
|
||||
import logcat.logcat
|
||||
|
||||
const val PASSWORD_FRAGMENT_TAG = "PasswordsList"
|
||||
|
||||
|
@ -108,18 +108,18 @@ class PasswordStore : BaseGitActivity() {
|
|||
val target = File(requireNotNull(intentData.getStringExtra("SELECTED_FOLDER_PATH")))
|
||||
val repositoryPath = PasswordRepository.getRepositoryDirectory().absolutePath
|
||||
if (!target.isDirectory) {
|
||||
e { "Tried moving passwords to a non-existing folder." }
|
||||
logcat(ERROR) { "Tried moving passwords to a non-existing folder." }
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
d { "Moving passwords to ${intentData.getStringExtra("SELECTED_FOLDER_PATH")}" }
|
||||
d { filesToMove.joinToString(", ") }
|
||||
logcat { "Moving passwords to ${intentData.getStringExtra("SELECTED_FOLDER_PATH")}" }
|
||||
logcat { filesToMove.joinToString(", ") }
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
for (file in filesToMove) {
|
||||
val source = File(file)
|
||||
if (!source.exists()) {
|
||||
e { "Tried moving something that appears non-existent." }
|
||||
logcat(ERROR) { "Tried moving something that appears non-existent." }
|
||||
continue
|
||||
}
|
||||
val destinationFile = File(target.absolutePath + "/" + source.name)
|
||||
|
@ -127,7 +127,7 @@ class PasswordStore : BaseGitActivity() {
|
|||
val sourceLongName = getLongName(requireNotNull(source.parent), repositoryPath, basename)
|
||||
val destinationLongName = getLongName(target.absolutePath, repositoryPath, basename)
|
||||
if (destinationFile.exists()) {
|
||||
e { "Trying to move a file that already exists." }
|
||||
logcat(ERROR) { "Trying to move a file that already exists." }
|
||||
withContext(Dispatchers.Main) {
|
||||
MaterialAlertDialogBuilder(this@PasswordStore)
|
||||
.setTitle(resources.getString(R.string.password_exists_title))
|
||||
|
@ -389,7 +389,7 @@ class PasswordStore : BaseGitActivity() {
|
|||
|
||||
private fun checkLocalRepository(localDir: File?) {
|
||||
if (localDir != null && settings.getBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false)) {
|
||||
d { "Check, dir: ${localDir.absolutePath}" }
|
||||
logcat { "Check, dir: ${localDir.absolutePath}" }
|
||||
// do not push the fragment if we already have it
|
||||
if (getPasswordFragment() == null || settings.getBoolean(PreferenceKeys.REPO_CHANGED, false)
|
||||
) {
|
||||
|
@ -454,7 +454,7 @@ class PasswordStore : BaseGitActivity() {
|
|||
fun createPassword() {
|
||||
if (!validateState()) return
|
||||
val currentDir = currentDir
|
||||
i { "Adding file to : ${currentDir.absolutePath}" }
|
||||
logcat(INFO) { "Adding file to : ${currentDir.absolutePath}" }
|
||||
val intent = Intent(this, PasswordCreationActivity::class.java)
|
||||
intent.putExtra("FILE_PATH", currentDir.absolutePath)
|
||||
intent.putExtra("REPO_PATH", PasswordRepository.getRepositoryDirectory().absolutePath)
|
||||
|
@ -632,7 +632,7 @@ class PasswordStore : BaseGitActivity() {
|
|||
mapOf(source to destinationFile)
|
||||
}
|
||||
if (!source.renameTo(destinationFile)) {
|
||||
e { "Something went wrong while moving $source to $destinationFile." }
|
||||
logcat(ERROR) { "Something went wrong while moving $source to $destinationFile." }
|
||||
withContext(Dispatchers.Main) {
|
||||
MaterialAlertDialogBuilder(this@PasswordStore)
|
||||
.setTitle(R.string.password_move_error_title)
|
||||
|
|
|
@ -12,11 +12,11 @@ import android.provider.DocumentsContract
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.edit
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
import logcat.logcat
|
||||
|
||||
class DirectorySelectionActivity : AppCompatActivity() {
|
||||
|
||||
|
@ -25,7 +25,7 @@ class DirectorySelectionActivity : AppCompatActivity() {
|
|||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri: Uri? ->
|
||||
if (uri == null) return@registerForActivityResult
|
||||
|
||||
d { "Selected repository URI is $uri" }
|
||||
logcat { "Selected repository URI is $uri" }
|
||||
// TODO: This is fragile. Workaround until PasswordItem is backed by DocumentFile
|
||||
val docId = DocumentsContract.getTreeDocumentId(uri)
|
||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
@ -33,7 +33,7 @@ class DirectorySelectionActivity : AppCompatActivity() {
|
|||
val repoPath = "${Environment.getExternalStorageDirectory()}/$path"
|
||||
val prefs = sharedPrefs
|
||||
|
||||
d { "Selected repository path is $repoPath" }
|
||||
logcat { "Selected repository path is $repoPath" }
|
||||
|
||||
if (Environment.getExternalStorageDirectory().path == repoPath) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
|
|
|
@ -12,9 +12,8 @@ import androidx.biometric.BiometricPrompt
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.github.ajalt.timberkt.Timber.tag
|
||||
import com.github.ajalt.timberkt.d
|
||||
import dev.msfjarvis.aps.R
|
||||
import logcat.logcat
|
||||
|
||||
object BiometricAuthenticator {
|
||||
|
||||
|
@ -43,7 +42,7 @@ object BiometricAuthenticator {
|
|||
object : BiometricPrompt.AuthenticationCallback() {
|
||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||
super.onAuthenticationError(errorCode, errString)
|
||||
tag(TAG).d { "BiometricAuthentication error: errorCode=$errorCode, msg=$errString" }
|
||||
logcat(TAG) { "BiometricAuthentication error: errorCode=$errorCode, msg=$errString" }
|
||||
callback(
|
||||
when (errorCode) {
|
||||
BiometricPrompt.ERROR_CANCELED,
|
||||
|
|
|
@ -15,7 +15,6 @@ import android.service.autofill.SaveInfo
|
|||
import android.view.inputmethod.InlineSuggestionsRequest
|
||||
import android.widget.inline.InlinePresentationSpec
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.FillableForm
|
||||
import com.github.androidpasswordstore.autofillparser.fillWith
|
||||
|
@ -28,6 +27,9 @@ import dev.msfjarvis.aps.ui.autofill.AutofillPublisherChangedActivity
|
|||
import dev.msfjarvis.aps.ui.autofill.AutofillSaveActivity
|
||||
import dev.msfjarvis.aps.util.FeatureFlags
|
||||
import java.io.File
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
/** Implements [AutofillResponseBuilder]'s methods for API 30 and above */
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
|
@ -213,7 +215,7 @@ class Api30AutofillResponseBuilder(form: FillableForm) {
|
|||
callback.onSuccess(makeFillResponse(context, inlineSuggestionsRequest, matchedFiles))
|
||||
},
|
||||
failure = { e ->
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
callback.onSuccess(makePublisherChangedResponse(context, inlineSuggestionsRequest, e))
|
||||
}
|
||||
)
|
||||
|
|
|
@ -8,9 +8,6 @@ import android.content.Context
|
|||
import android.content.SharedPreferences
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.edit
|
||||
import com.github.ajalt.timberkt.Timber.e
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.w
|
||||
import com.github.androidpasswordstore.autofillparser.FormOrigin
|
||||
import com.github.androidpasswordstore.autofillparser.computeCertificatesHash
|
||||
import com.github.michaelbull.result.Err
|
||||
|
@ -18,6 +15,9 @@ import com.github.michaelbull.result.Ok
|
|||
import com.github.michaelbull.result.Result
|
||||
import dev.msfjarvis.aps.R
|
||||
import java.io.File
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.LogPriority.WARN
|
||||
import logcat.logcat
|
||||
|
||||
private const val PREFERENCES_AUTOFILL_APP_MATCHES = "oreo_autofill_app_matches"
|
||||
private val Context.autofillAppMatches
|
||||
|
@ -69,7 +69,7 @@ class AutofillMatcher {
|
|||
context.autofillAppMatches.getString(tokenKey(formOrigin), null) ?: return false
|
||||
val hashHasChanged = certificatesHash != storedCertificatesHash
|
||||
if (hashHasChanged) {
|
||||
e { "$packageName: stored=$storedCertificatesHash, new=$certificatesHash" }
|
||||
logcat(ERROR) { "$packageName: stored=$storedCertificatesHash, new=$certificatesHash" }
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -134,7 +134,7 @@ class AutofillMatcher {
|
|||
if (hasFormOriginHashChanged(context, formOrigin)) {
|
||||
// This should never happen since we already verified the publisher in
|
||||
// getMatchesFor.
|
||||
e { "App publisher changed between getMatchesFor and addMatchFor" }
|
||||
logcat(ERROR) { "App publisher changed between getMatchesFor and addMatchFor" }
|
||||
throw AutofillPublisherChangedException(formOrigin)
|
||||
}
|
||||
val matchPreferences = context.matchPreferences(formOrigin)
|
||||
|
@ -154,7 +154,7 @@ class AutofillMatcher {
|
|||
putStringSet(matchesKey(formOrigin), newFiles.map { it.absolutePath }.toSet())
|
||||
}
|
||||
storeFormOriginHash(context, formOrigin)
|
||||
d { "Stored match for $formOrigin" }
|
||||
logcat { "Stored match for $formOrigin" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,7 +176,7 @@ class AutofillMatcher {
|
|||
// created with `putStringSet`.
|
||||
@Suppress("UNCHECKED_CAST") val oldMatches = value as? Set<String>
|
||||
if (oldMatches == null) {
|
||||
w { "Failed to read matches for $key" }
|
||||
logcat(WARN) { "Failed to read matches for $key" }
|
||||
continue
|
||||
}
|
||||
// Delete all matches for file locations that are going to be overwritten, then
|
||||
|
@ -188,7 +188,7 @@ class AutofillMatcher {
|
|||
.minus(oldNewPathMap.values)
|
||||
.map { match ->
|
||||
val newPath = oldNewPathMap[match] ?: return@map match
|
||||
d { "Updating match for $key: $match --> $newPath" }
|
||||
logcat { "Updating match for $key: $match --> $newPath" }
|
||||
newPath
|
||||
}
|
||||
.toSet()
|
||||
|
|
|
@ -13,7 +13,6 @@ import android.service.autofill.FillCallback
|
|||
import android.service.autofill.FillResponse
|
||||
import android.service.autofill.SaveInfo
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillScenario
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
|
@ -28,6 +27,9 @@ import dev.msfjarvis.aps.ui.autofill.AutofillPublisherChangedActivity
|
|||
import dev.msfjarvis.aps.ui.autofill.AutofillSaveActivity
|
||||
import dev.msfjarvis.aps.util.FeatureFlags
|
||||
import java.io.File
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutofillResponseBuilder(form: FillableForm) {
|
||||
|
@ -180,7 +182,7 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||
.fold(
|
||||
success = { matchedFiles -> callback.onSuccess(makeFillResponse(context, matchedFiles)) },
|
||||
failure = { e ->
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
callback.onSuccess(makePublisherChangedResponse(context, e))
|
||||
}
|
||||
)
|
||||
|
@ -209,7 +211,7 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||
}
|
||||
return builder.run {
|
||||
if (scenario != null) fillWith(scenario, action, credentials)
|
||||
else e { "Failed to recover scenario from client state" }
|
||||
else logcat(ERROR) { "Failed to recover scenario from client state" }
|
||||
build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import androidx.core.content.getSystemService
|
|||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKey
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.michaelbull.result.Ok
|
||||
import com.github.michaelbull.result.Result
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
@ -29,6 +28,7 @@ import dev.msfjarvis.aps.BuildConfig
|
|||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||
import dev.msfjarvis.aps.util.git.operation.GitOperation
|
||||
import logcat.logcat
|
||||
|
||||
/** Get an instance of [AutofillManager]. Only available on Android Oreo and above */
|
||||
val Context.autofillManager: AutofillManager?
|
||||
|
@ -91,7 +91,7 @@ suspend fun FragmentActivity.commitChange(
|
|||
)
|
||||
|
||||
override fun preExecute(): Boolean {
|
||||
d { "Committing with message: '$message'" }
|
||||
logcat { "Committing with message: '$message'" }
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.github.michaelbull.result.runCatching
|
|||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
import logcat.asLog
|
||||
import org.eclipse.jgit.lib.ObjectId
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
|
@ -78,3 +79,6 @@ fun String.splitLines(): Array<String> {
|
|||
|
||||
/** Alias to [lazy] with thread safety mode always set to [LazyThreadSafetyMode.NONE]. */
|
||||
fun <T> unsafeLazy(initializer: () -> T) = lazy(LazyThreadSafetyMode.NONE) { initializer.invoke() }
|
||||
|
||||
/** A convenience extension to turn a [Throwable] with a message into a loggable string. */
|
||||
fun Throwable.asLog(message: String): String = "$message\n${asLog()}"
|
||||
|
|
|
@ -5,24 +5,28 @@
|
|||
|
||||
package dev.msfjarvis.aps.util.git
|
||||
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||
import dev.msfjarvis.aps.util.extensions.asLog
|
||||
import dev.msfjarvis.aps.util.extensions.hash
|
||||
import dev.msfjarvis.aps.util.extensions.time
|
||||
import dev.msfjarvis.aps.util.extensions.unsafeLazy
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
private val TAG = GitLogModel::class.java.simpleName
|
||||
|
||||
private fun commits(): Iterable<RevCommit> {
|
||||
val repo = PasswordRepository.getRepository(null)
|
||||
if (repo == null) {
|
||||
e { "Could not access git repository" }
|
||||
logcat(TAG, ERROR) { "Could not access git repository" }
|
||||
return listOf()
|
||||
}
|
||||
return runCatching { Git(repo).log().call() }.getOrElse { e ->
|
||||
e(e) { "Failed to obtain git commits" }
|
||||
logcat(TAG, ERROR) { e.asLog("Failed to obtain git commits") }
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +52,8 @@ class GitLogModel {
|
|||
val size = cache.size
|
||||
|
||||
fun get(index: Int): GitCommit? {
|
||||
if (index >= size) e { "Cannot get git commit with index $index. There are only $size." }
|
||||
if (index >= size)
|
||||
logcat(ERROR) { "Cannot get git commit with index $index. There are only $size." }
|
||||
return cache.getOrNull(index)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ package dev.msfjarvis.aps.util.git.operation
|
|||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.Err
|
||||
import com.github.michaelbull.result.Ok
|
||||
import com.github.michaelbull.result.Result
|
||||
|
@ -34,6 +33,9 @@ import kotlin.coroutines.resume
|
|||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import net.schmizz.sshj.common.DisconnectReason
|
||||
import net.schmizz.sshj.common.SSHException
|
||||
import net.schmizz.sshj.userauth.password.PasswordFinder
|
||||
|
@ -110,7 +112,7 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
|
|||
}
|
||||
callingActivity.startActivity(intent)
|
||||
}
|
||||
.onFailure { e -> e(e) }
|
||||
.onFailure { e -> logcat(ERROR) { e.asLog() } }
|
||||
}
|
||||
|
||||
private fun registerAuthProviders(
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.content.Intent
|
|||
import androidx.activity.result.IntentSenderRequest
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.d
|
||||
import dev.msfjarvis.aps.util.extensions.OPENPGP_PROVIDER
|
||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
|
@ -21,6 +20,7 @@ import kotlin.coroutines.suspendCoroutine
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.logcat
|
||||
import net.schmizz.sshj.common.DisconnectReason
|
||||
import net.schmizz.sshj.common.KeyType
|
||||
import net.schmizz.sshj.userauth.UserAuthException
|
||||
|
@ -81,7 +81,7 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
|
|||
sshServiceConnection.connect(
|
||||
object : SshAuthenticationConnection.OnBound {
|
||||
override fun onBound(sshAgent: ISshAuthenticationService) {
|
||||
d { "Bound to SshAuthenticationApi: $OPENPGP_PROVIDER" }
|
||||
logcat { "Bound to SshAuthenticationApi: $OPENPGP_PROVIDER" }
|
||||
cont.resume(SshAuthenticationApi(context, sshAgent))
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
|
|||
request: Request,
|
||||
resultOfUserInteraction: Intent? = null
|
||||
): ApiResponse {
|
||||
d { "executeRequest($request) called" }
|
||||
logcat { "executeRequest($request) called" }
|
||||
val result =
|
||||
withContext(Dispatchers.Main) {
|
||||
// If the request required user interaction, the data returned from the
|
||||
|
@ -142,7 +142,7 @@ class OpenKeychainKeyProvider private constructor(val activity: ContinuationCont
|
|||
// is used as the real request.
|
||||
sshServiceApi.executeApi(resultOfUserInteraction ?: request.toIntent())!!
|
||||
}
|
||||
return parseResult(request, result).also { d { "executeRequest($request): $it" } }
|
||||
return parseResult(request, result).also { logcat { "executeRequest($request): $it" } }
|
||||
}
|
||||
|
||||
private suspend fun parseResult(request: Request, result: Intent): ApiResponse {
|
||||
|
|
|
@ -16,8 +16,6 @@ import android.util.Base64
|
|||
import androidx.core.content.edit
|
||||
import androidx.security.crypto.EncryptedFile
|
||||
import androidx.security.crypto.MasterKey
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import dev.msfjarvis.aps.Application
|
||||
|
@ -39,6 +37,8 @@ import javax.crypto.SecretKeyFactory
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
|
||||
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec
|
||||
|
@ -101,7 +101,7 @@ object SshKey {
|
|||
// It is fine to swallow the exception here since it will reappear when the key
|
||||
// is
|
||||
// used for SSH authentication and can then be shown in the UI.
|
||||
d(error)
|
||||
logcat { error.asLog() }
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -317,13 +317,13 @@ object SshKey {
|
|||
|
||||
override fun getPublic(): PublicKey =
|
||||
runCatching { androidKeystore.sshPublicKey!! }.getOrElse { error ->
|
||||
e(error)
|
||||
logcat { error.asLog() }
|
||||
throw IOException("Failed to get public key '$KEYSTORE_ALIAS' from Android Keystore", error)
|
||||
}
|
||||
|
||||
override fun getPrivate(): PrivateKey =
|
||||
runCatching { androidKeystore.sshPrivateKey!! }.getOrElse { error ->
|
||||
e(error)
|
||||
logcat { error.asLog() }
|
||||
throw IOException(
|
||||
"Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
|
||||
error
|
||||
|
@ -337,7 +337,7 @@ object SshKey {
|
|||
|
||||
override fun getPublic(): PublicKey =
|
||||
runCatching { parseSshPublicKey(sshPublicKey!!)!! }.getOrElse { error ->
|
||||
e(error)
|
||||
logcat { error.asLog() }
|
||||
throw IOException("Failed to get the public key for wrapped ed25519 key", error)
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ object SshKey {
|
|||
)
|
||||
}
|
||||
.getOrElse { error ->
|
||||
e(error)
|
||||
logcat { error.asLog() }
|
||||
throw IOException("Failed to unwrap wrapped ed25519 key", error)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
*/
|
||||
package dev.msfjarvis.aps.util.git.sshj
|
||||
|
||||
import com.github.ajalt.timberkt.Timber
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import com.hierynomus.sshj.key.KeyAlgorithms
|
||||
import com.hierynomus.sshj.transport.cipher.BlockCiphers
|
||||
|
@ -14,6 +12,12 @@ import com.hierynomus.sshj.transport.kex.ExtInfoClientFactory
|
|||
import com.hierynomus.sshj.transport.mac.Macs
|
||||
import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile
|
||||
import java.security.Security
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.LogPriority.INFO
|
||||
import logcat.LogPriority.VERBOSE
|
||||
import logcat.LogPriority.WARN
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
import net.schmizz.keepalive.KeepAliveProvider
|
||||
import net.schmizz.sshj.ConfigImpl
|
||||
import net.schmizz.sshj.common.LoggerFactory
|
||||
|
@ -49,7 +53,9 @@ fun setUpBouncyCastleForSshj() {
|
|||
runCatching { Class.forName("sun.security.jca.Providers") }
|
||||
Security.insertProviderAt(BouncyCastleProvider(), bcIndex + 1)
|
||||
}
|
||||
d { "JCE providers: ${Security.getProviders().joinToString { "${it.name} (${it.version})" }}" }
|
||||
logcat("setUpBouncyCastleForSshj") {
|
||||
"JCE providers: ${Security.getProviders().joinToString { "${it.name} (${it.version})" }}"
|
||||
}
|
||||
// Prevent sshj from forwarding all cryptographic operations to BC.
|
||||
SecurityUtils.setRegisterBouncyCastle(false)
|
||||
SecurityUtils.setSecurityProvider(null)
|
||||
|
@ -147,10 +153,9 @@ private abstract class AbstractLogger(private val name: String) : Logger {
|
|||
override fun error(marker: Marker?, msg: String, t: Throwable?) = error(msg, t)
|
||||
}
|
||||
|
||||
object TimberLoggerFactory : LoggerFactory {
|
||||
private class TimberLogger(name: String) : AbstractLogger(name) {
|
||||
object LogcatLoggerFactory : LoggerFactory {
|
||||
private class LogcatLogger(name: String) : AbstractLogger(name) {
|
||||
|
||||
// We defer the log level checks to Timber.
|
||||
override fun isTraceEnabled() = true
|
||||
override fun isDebugEnabled() = true
|
||||
override fun isInfoEnabled() = true
|
||||
|
@ -163,39 +168,39 @@ object TimberLoggerFactory : LoggerFactory {
|
|||
private fun String.fix() = replace("""(?!<\\)\{\}""".toRegex(), "%s")
|
||||
|
||||
override fun t(message: String, t: Throwable?, vararg args: Any?) {
|
||||
Timber.tag(name).v(t, message.fix(), *args)
|
||||
logcat(name, VERBOSE) { message.fix().format(*args) + (t?.asLog() ?: "") }
|
||||
}
|
||||
|
||||
override fun d(message: String, t: Throwable?, vararg args: Any?) {
|
||||
Timber.tag(name).d(t, message.fix(), *args)
|
||||
logcat(name) { message.fix().format(*args) + (t?.asLog() ?: "") }
|
||||
}
|
||||
|
||||
override fun i(message: String, t: Throwable?, vararg args: Any?) {
|
||||
Timber.tag(name).i(t, message.fix(), *args)
|
||||
logcat(name, INFO) { message.fix().format(*args) + (t?.asLog() ?: "") }
|
||||
}
|
||||
|
||||
override fun w(message: String, t: Throwable?, vararg args: Any?) {
|
||||
Timber.tag(name).w(t, message.fix(), *args)
|
||||
logcat(name, WARN) { message.fix().format(*args) + (t?.asLog() ?: "") }
|
||||
}
|
||||
|
||||
override fun e(message: String, t: Throwable?, vararg args: Any?) {
|
||||
Timber.tag(name).e(t, message.fix(), *args)
|
||||
logcat(name, ERROR) { message.fix().format(*args) + (t?.asLog() ?: "") }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLogger(name: String): Logger {
|
||||
return TimberLogger(name)
|
||||
return LogcatLogger(name)
|
||||
}
|
||||
|
||||
override fun getLogger(clazz: Class<*>): Logger {
|
||||
return TimberLogger(clazz.name)
|
||||
return LogcatLogger(clazz.name)
|
||||
}
|
||||
}
|
||||
|
||||
class SshjConfig : ConfigImpl() {
|
||||
|
||||
init {
|
||||
loggerFactory = TimberLoggerFactory
|
||||
loggerFactory = LogcatLoggerFactory
|
||||
keepAliveProvider = KeepAliveProvider.HEARTBEAT
|
||||
version = "OpenSSH_8.2p1 Ubuntu-4ubuntu0.1"
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
package dev.msfjarvis.aps.util.git.sshj
|
||||
|
||||
import android.util.Base64
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.w
|
||||
import com.github.michaelbull.result.getOrElse
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import dev.msfjarvis.aps.util.git.operation.CredentialFinder
|
||||
|
@ -20,6 +18,8 @@ import kotlin.coroutines.Continuation
|
|||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority.WARN
|
||||
import logcat.logcat
|
||||
import net.schmizz.sshj.SSHClient
|
||||
import net.schmizz.sshj.common.Buffer.PlainBuffer
|
||||
import net.schmizz.sshj.common.DisconnectReason
|
||||
|
@ -76,7 +76,7 @@ class SshjSessionFactory(private val authMethod: SshAuthMethod, private val host
|
|||
): RemoteSession {
|
||||
return currentSession
|
||||
?: SshjSession(uri, uri.user, authMethod, hostKeyFile).connect().also {
|
||||
d { "New SSH connection created" }
|
||||
logcat { "New SSH connection created" }
|
||||
currentSession = it
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +96,15 @@ private fun makeTofuHostKeyVerifier(hostKeyFile: File): HostKeyVerifier {
|
|||
digest.update(PlainBuffer().putPublicKey(key).compactData)
|
||||
val digestData = digest.digest()
|
||||
val hostKeyEntry = "SHA256:${Base64.encodeToString(digestData, Base64.NO_WRAP)}"
|
||||
d { "Trusting host key on first use: $hostKeyEntry" }
|
||||
logcat(SshjSessionFactory::class.java.simpleName) {
|
||||
"Trusting host key on first use: $hostKeyEntry"
|
||||
}
|
||||
hostKeyFile.writeText(hostKeyEntry)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
val hostKeyEntry = hostKeyFile.readText()
|
||||
d { "Pinned host key: $hostKeyEntry" }
|
||||
logcat(SshjSessionFactory::class.java.simpleName) { "Pinned host key: $hostKeyEntry" }
|
||||
return FingerprintVerifier.getInstance(hostKeyEntry)
|
||||
}
|
||||
}
|
||||
|
@ -122,12 +124,12 @@ private class SshjSession(
|
|||
// URIish's String constructor cannot handle '@' in the user part of the URI and the URL
|
||||
// constructor can't be used since Java's URL does not recognize the ssh scheme. We thus
|
||||
// need to patch everything up ourselves.
|
||||
d { "Before fixup: user=${uri.user}, host=${uri.host}" }
|
||||
logcat { "Before fixup: user=${uri.user}, host=${uri.host}" }
|
||||
val userPlusHost = "${uri.user}@${uri.host}"
|
||||
val realUser = userPlusHost.substringBeforeLast('@')
|
||||
val realHost = userPlusHost.substringAfterLast('@')
|
||||
uri.setUser(realUser).setHost(realHost).also {
|
||||
d { "After fixup: user=${it.user}, host=${it.host}" }
|
||||
logcat { "After fixup: user=${it.user}, host=${it.host}" }
|
||||
}
|
||||
} else {
|
||||
uri
|
||||
|
@ -162,7 +164,7 @@ private class SshjSession(
|
|||
|
||||
override fun exec(commandName: String?, timeout: Int): Process {
|
||||
if (currentCommand != null) {
|
||||
w { "Killing old command" }
|
||||
logcat(WARN) { "Killing old command" }
|
||||
disconnect()
|
||||
}
|
||||
val session = ssh.startSession()
|
||||
|
|
|
@ -16,7 +16,6 @@ import android.os.IBinder
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import com.github.ajalt.timberkt.d
|
||||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.util.extensions.clipboard
|
||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||
|
@ -29,6 +28,7 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.logcat
|
||||
|
||||
class ClipboardService : Service() {
|
||||
|
||||
|
@ -82,7 +82,7 @@ class ClipboardService : Service() {
|
|||
|
||||
if (clipboard != null) {
|
||||
scope.launch {
|
||||
d { "Clearing the clipboard" }
|
||||
logcat { "Clearing the clipboard" }
|
||||
val clip = ClipData.newPlainText("pgp_handler_result_pm", "")
|
||||
clipboard.setPrimaryClip(clip)
|
||||
if (deepClear) {
|
||||
|
@ -95,7 +95,7 @@ class ClipboardService : Service() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
d { "Cannot get clipboard manager service" }
|
||||
logcat { "Cannot get clipboard manager service" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ class ClipboardService : Service() {
|
|||
if (manager != null) {
|
||||
manager.createNotificationChannel(serviceChannel)
|
||||
} else {
|
||||
d { "Failed to create notification channel" }
|
||||
logcat { "Failed to create notification channel" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ import android.service.autofill.FillResponse
|
|||
import android.service.autofill.SaveCallback
|
||||
import android.service.autofill.SaveRequest
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillScenario
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
import com.github.androidpasswordstore.autofillparser.FillableForm
|
||||
|
@ -34,6 +32,8 @@ import dev.msfjarvis.aps.util.extensions.getString
|
|||
import dev.msfjarvis.aps.util.extensions.hasFlag
|
||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class OreoAutofillService : AutofillService() {
|
||||
|
@ -92,7 +92,7 @@ class OreoAutofillService : AutofillService() {
|
|||
getCustomSuffixes(),
|
||||
)
|
||||
?: run {
|
||||
d { "Form cannot be filled" }
|
||||
logcat { "Form cannot be filled" }
|
||||
callback.onSuccess(null)
|
||||
return
|
||||
}
|
||||
|
@ -117,21 +117,21 @@ class OreoAutofillService : AutofillService() {
|
|||
val clientState =
|
||||
request.clientState
|
||||
?: run {
|
||||
e { "Received save request without client state" }
|
||||
logcat(ERROR) { "Received save request without client state" }
|
||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||
return
|
||||
}
|
||||
val scenario =
|
||||
AutofillScenario.fromClientState(clientState)?.recoverNodes(structure)
|
||||
?: run {
|
||||
e { "Failed to recover client state or nodes from client state" }
|
||||
logcat(ERROR) { "Failed to recover client state or nodes from client state" }
|
||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||
return
|
||||
}
|
||||
val formOrigin =
|
||||
FormOrigin.fromBundle(clientState)
|
||||
?: run {
|
||||
e { "Failed to recover form origin from client state" }
|
||||
logcat(ERROR) { "Failed to recover form origin from client state" }
|
||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ import android.os.IBinder
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.github.ajalt.timberkt.d
|
||||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Calendar
|
||||
import java.util.TimeZone
|
||||
import logcat.logcat
|
||||
|
||||
class PasswordExportService : Service() {
|
||||
|
||||
|
@ -62,7 +62,7 @@ class PasswordExportService : Service() {
|
|||
val repositoryDirectory = requireNotNull(PasswordRepository.getRepositoryDirectory())
|
||||
val sourcePassDir = DocumentFile.fromFile(repositoryDirectory)
|
||||
|
||||
d { "Copying ${repositoryDirectory.path} to $targetDirectory" }
|
||||
logcat { "Copying ${repositoryDirectory.path} to $targetDirectory" }
|
||||
|
||||
val dateString =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
@ -146,7 +146,7 @@ class PasswordExportService : Service() {
|
|||
if (manager != null) {
|
||||
manager.createNotificationChannel(serviceChannel)
|
||||
} else {
|
||||
d { "Failed to create notification channel" }
|
||||
logcat { "Failed to create notification channel" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,17 @@ package dev.msfjarvis.aps.util.settings
|
|||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.ajalt.timberkt.i
|
||||
import com.github.michaelbull.result.get
|
||||
import com.github.michaelbull.result.runCatching
|
||||
import dev.msfjarvis.aps.util.extensions.getString
|
||||
import dev.msfjarvis.aps.util.git.sshj.SshKey
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.LogPriority.INFO
|
||||
import logcat.logcat
|
||||
|
||||
private const val TAG = "Migrations"
|
||||
|
||||
fun runMigrations(filesDirPath: String, sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
|
||||
migrateToGitUrlBasedConfig(sharedPrefs, gitSettings)
|
||||
|
@ -26,7 +29,7 @@ fun runMigrations(filesDirPath: String, sharedPrefs: SharedPreferences, gitSetti
|
|||
|
||||
private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
|
||||
val serverHostname = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_SERVER) ?: return
|
||||
i { "Migrating to URL-based Git config" }
|
||||
logcat(TAG, INFO) { "Migrating to URL-based Git config" }
|
||||
val serverPort = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PORT) ?: ""
|
||||
val serverUser = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_USERNAME) ?: ""
|
||||
val serverPath = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_LOCATION) ?: ""
|
||||
|
@ -79,7 +82,7 @@ private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences, gitSettin
|
|||
newBranch = gitSettings.branch
|
||||
) != GitSettings.UpdateConnectionSettingsResult.Valid
|
||||
) {
|
||||
e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
|
||||
logcat(TAG, ERROR) { "Failed to migrate to URL-based Git config, generated URL is invalid" }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ import android.graphics.drawable.Icon
|
|||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.getSystemService
|
||||
import com.github.ajalt.timberkt.d
|
||||
import dagger.Reusable
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dev.msfjarvis.aps.R
|
||||
import dev.msfjarvis.aps.data.password.PasswordItem
|
||||
import javax.inject.Inject
|
||||
import logcat.logcat
|
||||
|
||||
@Reusable
|
||||
class ShortcutHandler
|
||||
|
@ -70,7 +70,7 @@ constructor(
|
|||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
||||
val shortcutManager: ShortcutManager = context.getSystemService() ?: return
|
||||
if (!shortcutManager.isRequestPinShortcutSupported) {
|
||||
d { "addPinnedShortcut: pin shortcuts unsupported" }
|
||||
logcat { "addPinnedShortcut: pin shortcuts unsupported" }
|
||||
return
|
||||
}
|
||||
val shortcut = buildShortcut(item, intent)
|
||||
|
|
|
@ -17,8 +17,6 @@ import android.view.autofill.AutofillManager
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.ajalt.timberkt.e
|
||||
import com.github.ajalt.timberkt.w
|
||||
import com.github.androidpasswordstore.autofillparser.AutofillAction
|
||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||
import com.github.michaelbull.result.onFailure
|
||||
|
@ -39,6 +37,8 @@ import kotlin.coroutines.suspendCoroutine
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority.WARN
|
||||
import logcat.logcat
|
||||
|
||||
suspend fun <T> Task<T>.suspendableAwait() =
|
||||
suspendCoroutine<T> { cont ->
|
||||
|
@ -62,14 +62,14 @@ class AutofillSmsActivity : AppCompatActivity() {
|
|||
val googleApiAvailabilityInstance = GoogleApiAvailability.getInstance()
|
||||
val googleApiStatus = googleApiAvailabilityInstance.isGooglePlayServicesAvailable(context)
|
||||
if (googleApiStatus != ConnectionResult.SUCCESS) {
|
||||
w {
|
||||
logcat(WARN) {
|
||||
"Google Play Services unavailable or not updated: ${googleApiAvailabilityInstance.getErrorString(googleApiStatus)}"
|
||||
}
|
||||
return false
|
||||
}
|
||||
// https://developer.android.com/guide/topics/text/autofill-services#sms-autofill
|
||||
if (googleApiAvailabilityInstance.getApkVersion(context) < 190056000) {
|
||||
w { "Google Play Service 19.0.56 or higher required for SMS OTP Autofill" }
|
||||
logcat(WARN) { "Google Play Service 19.0.56 or higher required for SMS OTP Autofill" }
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -103,7 +103,7 @@ class AutofillSmsActivity : AppCompatActivity() {
|
|||
clientState =
|
||||
intent?.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE)
|
||||
?: run {
|
||||
e { "AutofillSmsActivity started without EXTRA_CLIENT_STATE" }
|
||||
logcat(WARN) { "AutofillSmsActivity started without EXTRA_CLIENT_STATE" }
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -21,6 +21,6 @@ dependencies {
|
|||
implementation(libs.androidx.autofill)
|
||||
implementation(libs.kotlin.coroutines.android)
|
||||
implementation(libs.kotlin.coroutines.core)
|
||||
implementation(libs.thirdparty.timberkt)
|
||||
implementation(libs.thirdparty.logcat)
|
||||
testImplementation(libs.bundles.testDependencies)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.view.autofill.AutofillId
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.d
|
||||
import logcat.logcat
|
||||
|
||||
/**
|
||||
* A unique identifier for either an Android app (package name) or a website (origin minus port).
|
||||
|
@ -84,7 +84,7 @@ private class AutofillFormParser(
|
|||
private val webOrigins = mutableSetOf<String>()
|
||||
|
||||
init {
|
||||
d { "Request from $appPackage (${computeCertificatesHash(context, appPackage)})" }
|
||||
logcat { "Request from $appPackage (${computeCertificatesHash(context, appPackage)})" }
|
||||
parseStructure(structure)
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ private class AutofillFormParser(
|
|||
val formOrigin = determineFormOrigin(context)
|
||||
|
||||
init {
|
||||
d { "Origin: $formOrigin" }
|
||||
logcat { "Origin: $formOrigin" }
|
||||
}
|
||||
|
||||
private fun parseStructure(structure: AssistStructure) {
|
||||
|
@ -111,11 +111,11 @@ private class AutofillFormParser(
|
|||
FormField(node, fieldIndex, false)
|
||||
}
|
||||
if (field.relevantField) {
|
||||
d { "Relevant: $field" }
|
||||
logcat { "Relevant: $field" }
|
||||
relevantFields.add(field)
|
||||
fieldIndex++
|
||||
} else {
|
||||
d { "Ignored : $field" }
|
||||
logcat { "Ignored : $field" }
|
||||
ignoredIds.add(field.autofillId)
|
||||
}
|
||||
for (i in 0 until node.childCount) {
|
||||
|
@ -134,7 +134,7 @@ private class AutofillFormParser(
|
|||
if (trustedBrowserInfo == null) return
|
||||
node.webOrigin?.let {
|
||||
if (it !in webOrigins) {
|
||||
d { "Origin encountered: $it" }
|
||||
logcat { "Origin encountered: $it" }
|
||||
webOrigins.add(it)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import android.util.Base64
|
|||
import android.view.autofill.AutofillId
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.Timber.tag
|
||||
import com.github.ajalt.timberkt.e
|
||||
import java.security.MessageDigest
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.logcat
|
||||
|
||||
private fun ByteArray.sha256(): ByteArray {
|
||||
return MessageDigest.getInstance("SHA-256").run {
|
||||
|
@ -59,7 +59,7 @@ public fun computeCertificatesHash(context: Context, appPackage: String): String
|
|||
info.signingInfo.signingCertificateHistory ?: info.signingInfo.apkContentsSigners
|
||||
val stableHashNew = stableHash(signaturesNew.map { it.toByteArray() })
|
||||
if (stableHashNew != stableHashOld)
|
||||
tag("CertificatesHash").e {
|
||||
logcat("CertificatesHash", ERROR) {
|
||||
"Mismatch between old and new hash: $stableHashNew != $stableHashOld"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import android.service.autofill.Dataset
|
|||
import android.view.autofill.AutofillId
|
||||
import android.view.autofill.AutofillValue
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.e
|
||||
import logcat.LogPriority.ERROR
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
public enum class AutofillAction {
|
||||
Match,
|
||||
|
@ -68,7 +70,7 @@ public sealed class AutofillScenario<out T : Any> {
|
|||
}
|
||||
.build()
|
||||
} catch (e: Throwable) {
|
||||
e(e)
|
||||
logcat(ERROR) { e.asLog() }
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ package com.github.androidpasswordstore.autofillparser
|
|||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.w
|
||||
import logcat.LogPriority.WARN
|
||||
import logcat.logcat
|
||||
|
||||
@DslMarker internal annotation class AutofillDsl
|
||||
|
||||
|
@ -116,16 +116,16 @@ internal class SingleFieldMatcher(
|
|||
val new = current.filter { tieBreaker(it, alreadyMatched) }
|
||||
// skipping those tie breakers that are not satisfied for any remaining field...
|
||||
if (new.isEmpty()) {
|
||||
d { "Tie breaker #${i + 1}: Didn't match any field; skipping" }
|
||||
logcat { "Tie breaker #${i + 1}: Didn't match any field; skipping" }
|
||||
continue
|
||||
}
|
||||
// and return if the available options have been narrowed to a single field.
|
||||
if (new.size == 1) {
|
||||
d { "Tie breaker #${i + 1}: Success" }
|
||||
logcat { "Tie breaker #${i + 1}: Success" }
|
||||
current = new
|
||||
break
|
||||
}
|
||||
d { "Tie breaker #${i + 1}: Matched ${new.size} fields; continuing" }
|
||||
logcat { "Tie breaker #${i + 1}: Matched ${new.size} fields; continuing" }
|
||||
current = new
|
||||
}
|
||||
listOf(current.singleOrNull() ?: return null)
|
||||
|
@ -154,16 +154,16 @@ private class PairOfFieldsMatcher(
|
|||
for ((i, tieBreaker) in tieBreakers.withIndex()) {
|
||||
val new = current.filter { tieBreaker(it, alreadyMatched) }
|
||||
if (new.isEmpty()) {
|
||||
d { "Tie breaker #${i + 1}: Didn't match any pair of fields; skipping" }
|
||||
logcat { "Tie breaker #${i + 1}: Didn't match any pair of fields; skipping" }
|
||||
continue
|
||||
}
|
||||
// and return if the available options have been narrowed to a single field.
|
||||
if (new.size == 1) {
|
||||
d { "Tie breaker #${i + 1}: Success" }
|
||||
logcat { "Tie breaker #${i + 1}: Success" }
|
||||
current = new
|
||||
break
|
||||
}
|
||||
d { "Tie breaker #${i + 1}: Matched ${new.size} pairs of fields; continuing" }
|
||||
logcat { "Tie breaker #${i + 1}: Matched ${new.size} pairs of fields; continuing" }
|
||||
current = new
|
||||
}
|
||||
current.singleOrNull()?.toList()
|
||||
|
@ -323,14 +323,14 @@ private constructor(
|
|||
isManualRequest: Boolean
|
||||
): AutofillScenario<FormField>? {
|
||||
if (singleOriginMode && !applyInSingleOriginMode) {
|
||||
d { "$name: Skipped in single origin mode" }
|
||||
logcat { "$name: Skipped in single origin mode" }
|
||||
return null
|
||||
}
|
||||
if (!isManualRequest && applyOnManualRequestOnly) {
|
||||
d { "$name: Skipped since not a manual request" }
|
||||
logcat { "$name: Skipped since not a manual request" }
|
||||
return null
|
||||
}
|
||||
d { "$name: Applying..." }
|
||||
logcat { "$name: Applying..." }
|
||||
val scenarioBuilder = AutofillScenario.Builder<FormField>()
|
||||
val alreadyMatched = mutableListOf<FormField>()
|
||||
for ((type, matcher, optional, matchHidden) in matchers) {
|
||||
|
@ -343,13 +343,13 @@ private constructor(
|
|||
val matchResult =
|
||||
matcher.match(fieldsToMatchOn, alreadyMatched)
|
||||
?: if (optional) {
|
||||
d { "$name: Skipping optional $type matcher" }
|
||||
logcat { "$name: Skipping optional $type matcher" }
|
||||
continue
|
||||
} else {
|
||||
d { "$name: Required $type matcher didn't match; passing to next rule" }
|
||||
logcat { "$name: Required $type matcher didn't match; passing to next rule" }
|
||||
return null
|
||||
}
|
||||
d { "$name: Matched $type" }
|
||||
logcat { "$name: Matched $type" }
|
||||
when (type) {
|
||||
FillableFieldType.Username -> {
|
||||
check(matchResult.size == 1 && scenarioBuilder.username == null)
|
||||
|
@ -370,9 +370,9 @@ private constructor(
|
|||
return scenarioBuilder.build().takeIf { scenario ->
|
||||
scenario.passesOriginCheck(singleOriginMode = singleOriginMode).also { passed ->
|
||||
if (passed) {
|
||||
d { "$name: Detected scenario:\n$scenario" }
|
||||
logcat { "$name: Detected scenario:\n$scenario" }
|
||||
} else {
|
||||
w { "$name: Scenario failed origin check:\n$scenario" }
|
||||
logcat(WARN) { "$name: Scenario failed origin check:\n$scenario" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -411,13 +411,13 @@ internal class AutofillStrategy private constructor(private val rules: List<Auto
|
|||
isManualRequest: Boolean
|
||||
): AutofillScenario<FormField>? {
|
||||
val possiblePasswordFields = fields.filter { it.passwordCertainty >= CertaintyLevel.Possible }
|
||||
d { "Possible password fields: ${possiblePasswordFields.size}" }
|
||||
logcat { "Possible password fields: ${possiblePasswordFields.size}" }
|
||||
val possibleUsernameFields = fields.filter { it.usernameCertainty >= CertaintyLevel.Possible }
|
||||
d { "Possible username fields: ${possibleUsernameFields.size}" }
|
||||
logcat { "Possible username fields: ${possibleUsernameFields.size}" }
|
||||
val possibleOtpFields = fields.filter { it.otpCertainty >= CertaintyLevel.Possible }
|
||||
d { "Possible otp fields: ${possibleOtpFields.size}" }
|
||||
logcat { "Possible otp fields: ${possibleOtpFields.size}" }
|
||||
// Return the result of the first rule that matches
|
||||
d { "Rules: ${rules.size}" }
|
||||
logcat { "Rules: ${rules.size}" }
|
||||
for (rule in rules) {
|
||||
return rule.match(
|
||||
possiblePasswordFields,
|
||||
|
|
|
@ -74,12 +74,11 @@ thirdparty-flowbinding-android = { module = "io.github.reactivecircus.flowbindin
|
|||
thirdparty-jgit = "org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r"
|
||||
thirdparty-kotlinResult = "com.michael-bull.kotlin-result:kotlin-result:1.1.12"
|
||||
thirdparty-leakcanary = "com.squareup.leakcanary:leakcanary-android:2.7"
|
||||
thirdparty-logcat = "com.squareup.logcat:logcat:0.1"
|
||||
thirdparty-modernAndroidPrefs = "de.maxr1998:modernandroidpreferences:2.1.0"
|
||||
thirdparty-plumber = "com.squareup.leakcanary:plumber-android:2.7"
|
||||
thirdparty-sshj = "com.hierynomus:sshj:0.31.0"
|
||||
thirdparty-sshauth = "com.github.open-keychain.open-keychain:sshauthentication-api:5.7.5"
|
||||
thirdparty-timber = "com.jakewharton.timber:timber:5.0.1"
|
||||
thirdparty-timberkt = "com.github.ajalt:timberkt:1.5.1"
|
||||
thirdparty-whatthestack = "com.github.haroldadmin:WhatTheStack:0.3.1"
|
||||
thirdparty-nonfree-googlePlayAuthApiPhone = "com.google.android.gms:play-services-auth-api-phone:17.5.1"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue