mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Merge pull request #477 from greenart7c3/claude/gate-logs-build-config-debug-6mps3l
Gate all logcat output behind BuildConfig.DEBUG
This commit is contained in:
@@ -7,12 +7,12 @@ import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationChannelCompat
|
||||
import androidx.core.app.NotificationChannelGroupCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.MainActivity
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.okhttp.HttpClientManager
|
||||
@@ -127,7 +127,7 @@ object TorManager {
|
||||
// Log all runtime events for debugging
|
||||
RuntimeEvent.entries().forEach { event ->
|
||||
observerStatic(event, OnEvent.Executor.Immediate) { data ->
|
||||
Log.d(TAG, data.toString())
|
||||
AmberLog.d(TAG, data.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,12 +137,12 @@ object TorManager {
|
||||
if (addr != null) {
|
||||
try {
|
||||
val port = addr.port.value
|
||||
Log.i(TAG, "Built-in Tor SOCKS proxy on port $port")
|
||||
AmberLog.i(TAG, "Built-in Tor SOCKS proxy on port $port")
|
||||
_socksPort.value = port
|
||||
_isRunning.value = true
|
||||
appContext?.let { showNotification(it.getString(R.string.builtin_tor_active)) }
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to read Tor SOCKS port", e)
|
||||
AmberLog.e(TAG, "Failed to read Tor SOCKS port", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,9 +154,9 @@ object TorManager {
|
||||
|
||||
torRuntime = runtime
|
||||
runtime.startDaemonAsync()
|
||||
Log.i(TAG, "Built-in Tor started")
|
||||
AmberLog.i(TAG, "Built-in Tor started")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to start built-in Tor", e)
|
||||
AmberLog.e(TAG, "Failed to start built-in Tor", e)
|
||||
torRuntime = null
|
||||
_isRunning.value = false
|
||||
}
|
||||
@@ -171,9 +171,9 @@ object TorManager {
|
||||
cancelNotification()
|
||||
try {
|
||||
runBlocking(Dispatchers.IO) { runtime.stopDaemonAsync() }
|
||||
Log.i(TAG, "Built-in Tor stopped")
|
||||
AmberLog.i(TAG, "Built-in Tor stopped")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error stopping built-in Tor", e)
|
||||
AmberLog.e(TAG, "Error stopping built-in Tor", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.content.Intent
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.TrafficStats
|
||||
import android.os.StrictMode
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.LruCache
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -98,7 +97,7 @@ class Amber :
|
||||
val pendingTranslationReport = MutableStateFlow<String?>(null)
|
||||
|
||||
fun setMainActivity(activity: AppCompatActivity?) {
|
||||
Log.d(TAG, "Setting main activity ref to $activity")
|
||||
AmberLog.d(TAG, "Setting main activity ref to $activity")
|
||||
mainActivityRef = WeakReference(activity)
|
||||
}
|
||||
|
||||
@@ -107,7 +106,7 @@ class Amber :
|
||||
// Exists to avoid exceptions stopping the coroutine
|
||||
val exceptionHandler =
|
||||
CoroutineExceptionHandler { _, throwable ->
|
||||
Log.e("AmberCoroutine", "Caught exception: ${throwable.message}", throwable)
|
||||
AmberLog.e("AmberCoroutine", "Caught exception: ${throwable.message}", throwable)
|
||||
if (throwable is FailedMigrationException) throw throwable
|
||||
}
|
||||
|
||||
@@ -159,7 +158,7 @@ class Amber :
|
||||
private var processLifecycleObserverRegistered = false
|
||||
private val processLifecycleObserver = object : DefaultLifecycleObserver {
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
Log.d("ProcessLifecycleOwner", "App in foreground")
|
||||
AmberLog.d("ProcessLifecycleOwner", "App in foreground")
|
||||
isAppInForeground = true
|
||||
|
||||
// activates the profile filter only when the app is in the foreground
|
||||
@@ -174,7 +173,7 @@ class Amber :
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
Log.d("ProcessLifecycleOwner", "App in background")
|
||||
AmberLog.d("ProcessLifecycleOwner", "App in background")
|
||||
isAppInForeground = false
|
||||
|
||||
// closes the filter when in the background
|
||||
@@ -230,7 +229,7 @@ class Amber :
|
||||
} else if (e.message?.contains("socket failed: EPERM (Operation not permitted)") == true) {
|
||||
ToastManager.toast(getString(R.string.warning), getString(R.string.network_permission_message))
|
||||
}
|
||||
Log.e(TAG, "Failed to connect to proxy", e)
|
||||
AmberLog.e(TAG, "Failed to connect to proxy", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -427,7 +426,7 @@ class Amber :
|
||||
}
|
||||
onDone()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to run migrations", e)
|
||||
AmberLog.e(TAG, "Failed to run migrations", e)
|
||||
if (e is CancellationException) throw e
|
||||
if (e is FailedMigrationException) throw e
|
||||
}
|
||||
@@ -447,7 +446,7 @@ class Amber :
|
||||
fun startService() {
|
||||
if (BuildFlavorChecker.isOfflineFlavor()) return
|
||||
try {
|
||||
Log.d(TAG, "Starting ConnectivityService")
|
||||
AmberLog.d(TAG, "Starting ConnectivityService")
|
||||
val operation = PendingIntent.getForegroundService(
|
||||
this,
|
||||
10,
|
||||
@@ -457,7 +456,7 @@ class Amber :
|
||||
val alarmManager = this.getSystemService(ALARM_SERVICE) as AlarmManager
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, 1000, operation)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to start ConnectivityService", e)
|
||||
AmberLog.e(TAG, "Failed to start ConnectivityService", e)
|
||||
if (e is CancellationException) throw e
|
||||
}
|
||||
}
|
||||
@@ -471,7 +470,7 @@ class Amber :
|
||||
if (settings.killSwitch.value) {
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "reconnecting relays")
|
||||
AmberLog.d(TAG, "reconnecting relays")
|
||||
val wasActive = client.isActive()
|
||||
// Always call connect() so that failed relays (socket == null) are retried
|
||||
// directly, bypassing BasicRelayClient's internal backoff delay. For relays
|
||||
@@ -552,7 +551,7 @@ class Amber :
|
||||
}
|
||||
notificationSubscription.updateFilter()
|
||||
}
|
||||
Log.d(TAG, "checkForNewRelaysAndUpdateAllFilters wasActive: $wasActive")
|
||||
AmberLog.d(TAG, "checkForNewRelaysAndUpdateAllFilters wasActive: $wasActive")
|
||||
if (!wasActive) {
|
||||
delay(3000)
|
||||
client.connect()
|
||||
@@ -604,11 +603,11 @@ class Amber :
|
||||
.eventListener(
|
||||
object : EventListener() {
|
||||
override fun onStart(request: ImageRequest) {
|
||||
Log.d(TAG, "Coil: loading ${request.data}")
|
||||
AmberLog.d(TAG, "Coil: loading ${request.data}")
|
||||
}
|
||||
|
||||
override fun onSuccess(request: ImageRequest, result: SuccessResult) {
|
||||
Log.d(
|
||||
AmberLog.d(
|
||||
TAG,
|
||||
"Coil: loaded ${request.data} from ${result.dataSource}" +
|
||||
" | mem=${memCache.size / 1024}/${memCache.maxSize / 1024} KB" +
|
||||
@@ -617,11 +616,11 @@ class Amber :
|
||||
}
|
||||
|
||||
override fun onError(request: ImageRequest, result: ErrorResult) {
|
||||
Log.w(TAG, "Coil: error loading ${request.data}", result.throwable)
|
||||
AmberLog.w(TAG, "Coil: error loading ${request.data}", result.throwable)
|
||||
}
|
||||
|
||||
override fun onCancel(request: ImageRequest) {
|
||||
Log.d(TAG, "Coil: cancelled ${request.data}")
|
||||
AmberLog.d(TAG, "Coil: cancelled ${request.data}")
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.greenart7c3.nostrsigner
|
||||
|
||||
import android.util.Log
|
||||
|
||||
/**
|
||||
* Thin wrapper around [android.util.Log] that only emits when running a debug
|
||||
* build. Release builds produce no logcat output, keeping potentially sensitive
|
||||
* data (npubs, relay URLs, event payloads) out of device logs.
|
||||
*
|
||||
* Mirrors the subset of the [Log] API used across the app. Prefer this over
|
||||
* [android.util.Log] everywhere so the debug gate stays in a single place.
|
||||
*/
|
||||
object AmberLog {
|
||||
fun v(tag: String, message: String) {
|
||||
if (BuildConfig.DEBUG) Log.v(tag, message)
|
||||
}
|
||||
|
||||
fun v(tag: String, message: String?, throwable: Throwable?) {
|
||||
if (BuildConfig.DEBUG) Log.v(tag, message, throwable)
|
||||
}
|
||||
|
||||
fun d(tag: String, message: String) {
|
||||
if (BuildConfig.DEBUG) Log.d(tag, message)
|
||||
}
|
||||
|
||||
fun d(tag: String, message: String?, throwable: Throwable?) {
|
||||
if (BuildConfig.DEBUG) Log.d(tag, message, throwable)
|
||||
}
|
||||
|
||||
fun i(tag: String, message: String) {
|
||||
if (BuildConfig.DEBUG) Log.i(tag, message)
|
||||
}
|
||||
|
||||
fun i(tag: String, message: String?, throwable: Throwable?) {
|
||||
if (BuildConfig.DEBUG) Log.i(tag, message, throwable)
|
||||
}
|
||||
|
||||
fun w(tag: String, message: String) {
|
||||
if (BuildConfig.DEBUG) Log.w(tag, message)
|
||||
}
|
||||
|
||||
fun w(tag: String, message: String?, throwable: Throwable?) {
|
||||
if (BuildConfig.DEBUG) Log.w(tag, message, throwable)
|
||||
}
|
||||
|
||||
fun e(tag: String, message: String) {
|
||||
if (BuildConfig.DEBUG) Log.e(tag, message)
|
||||
}
|
||||
|
||||
fun e(tag: String, message: String?, throwable: Throwable?) {
|
||||
if (BuildConfig.DEBUG) Log.e(tag, message, throwable)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.greenart7c3.nostrsigner
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
@@ -15,7 +14,7 @@ object DataStoreAccess {
|
||||
private val storeCache = ConcurrentHashMap<String, DataStore<Preferences>>()
|
||||
|
||||
private fun getDataStore(context: Context, npub: String): DataStore<Preferences> = storeCache.computeIfAbsent(npub) {
|
||||
Log.d(Amber.TAG, "Creating new DataStore for $npub on ${Thread.currentThread().name}")
|
||||
AmberLog.d(Amber.TAG, "Creating new DataStore for $npub on ${Thread.currentThread().name}")
|
||||
|
||||
PreferenceDataStoreFactory.create(
|
||||
scope = Amber.instance.applicationIOScope,
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.greenart7c3.nostrsigner
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.core.content.edit
|
||||
@@ -94,10 +93,10 @@ object LocalPreferences {
|
||||
|
||||
fun currentAccount(context: Context): String? {
|
||||
if (currentAccount == null) {
|
||||
Log.d(Amber.TAG, "currentAccount is null fetching from shared preferences")
|
||||
AmberLog.d(Amber.TAG, "currentAccount is null fetching from shared preferences")
|
||||
currentAccount = sharedPrefs(context).getString(SettingsKeys.CURRENT_ACCOUNT.key, null)
|
||||
if (currentAccount == null) {
|
||||
Log.d(Amber.TAG, "currentAccount is null fetching from all saved accounts")
|
||||
AmberLog.d(Amber.TAG, "currentAccount is null fetching from all saved accounts")
|
||||
currentAccount = allSavedAccounts(context).firstOrNull()?.npub
|
||||
}
|
||||
}
|
||||
@@ -356,9 +355,9 @@ object LocalPreferences {
|
||||
if (it.contains(npub)) {
|
||||
try {
|
||||
val result = File(prefsDir, it).delete()
|
||||
Log.d(Amber.TAG, "deleted $it: $result")
|
||||
AmberLog.d(Amber.TAG, "deleted $it: $result")
|
||||
} catch (e: Exception) {
|
||||
Log.d(Amber.TAG, "failed to delete $it", e)
|
||||
AmberLog.d(Amber.TAG, "failed to delete $it", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -472,7 +471,7 @@ object LocalPreferences {
|
||||
|
||||
fun loadFromEncryptedStorageSync(context: Context, npub: String? = null): Account? {
|
||||
if (savedAccounts == null || accountCache.size() == 0 || savedAccounts?.size != accountCache.size()) {
|
||||
Log.d(Amber.TAG, "accountCache is null loading accounts")
|
||||
AmberLog.d(Amber.TAG, "accountCache is null loading accounts")
|
||||
runBlocking {
|
||||
allSavedAccounts(context).forEach {
|
||||
loadFromEncryptedStorage(context, it.npub)
|
||||
@@ -641,11 +640,11 @@ object LocalPreferences {
|
||||
DataStoreAccess.NOSTR_PRIVKEY,
|
||||
)
|
||||
} catch (e: InvalidKeyException) {
|
||||
Log.e(Amber.TAG, "AndroidKeyStore key for $npub is broken (device KeyMint may not support key upgrade). Account skipped.", e)
|
||||
AmberLog.e(Amber.TAG, "AndroidKeyStore key for $npub is broken (device KeyMint may not support key upgrade). Account skipped.", e)
|
||||
Amber.instance.keystoreFailedAccounts.value = (Amber.instance.keystoreFailedAccounts.value + npub).distinct()
|
||||
return null
|
||||
} catch (e: KeyStoreException) {
|
||||
Log.e(Amber.TAG, "KeyStore operation failed for $npub. Account skipped.", e)
|
||||
AmberLog.e(Amber.TAG, "KeyStore operation failed for $npub. Account skipped.", e)
|
||||
Amber.instance.keystoreFailedAccounts.value = (Amber.instance.keystoreFailedAccounts.value + npub).distinct()
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.greenart7c3.nostrsigner
|
||||
import android.content.Intent
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@@ -50,7 +49,7 @@ class MainActivity : AppCompatActivity() {
|
||||
lateinit var mainViewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.d(Amber.TAG, "onCreate MainActivity")
|
||||
AmberLog.d(Amber.TAG, "onCreate MainActivity")
|
||||
Amber.isAppInForeground = true
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -61,7 +60,7 @@ class MainActivity : AppCompatActivity() {
|
||||
HttpClientManager.setDefaultUserAgent("Amber/${BuildConfig.VERSION_NAME}")
|
||||
|
||||
if (intent?.isLaunchFromHistory() == true) {
|
||||
Log.d(Amber.TAG, "Cleared intent history")
|
||||
AmberLog.d(Amber.TAG, "Cleared intent history")
|
||||
intent = Intent()
|
||||
}
|
||||
|
||||
@@ -122,13 +121,13 @@ class MainActivity : AppCompatActivity() {
|
||||
val currentAccount = LocalPreferences.currentAccount(context)
|
||||
if (currentAccount != null && localNpub != null && currentAccount != localNpub && localNpub.isNotBlank()) {
|
||||
if (localNpub.startsWith("npub")) {
|
||||
Log.d(Amber.TAG, "Switching account to $localNpub")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $localNpub")
|
||||
if (LocalPreferences.containsAccount(context, localNpub)) {
|
||||
accountStateViewModel.switchUser(localNpub, Route.IncomingRequest.route)
|
||||
}
|
||||
} else {
|
||||
val localNpub2 = Hex.decode(localNpub).toNpub()
|
||||
Log.d(Amber.TAG, "Switching account to $localNpub2")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $localNpub2")
|
||||
if (LocalPreferences.containsAccount(context, localNpub2)) {
|
||||
accountStateViewModel.switchUser(localNpub2, Route.IncomingRequest.route)
|
||||
}
|
||||
@@ -153,13 +152,13 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
Log.d(Amber.TAG, "onPause MainActivity")
|
||||
AmberLog.d(Amber.TAG, "onPause MainActivity")
|
||||
Amber.isAppInForeground = false
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
Log.d(Amber.TAG, "onResume MainActivity")
|
||||
AmberLog.d(Amber.TAG, "onResume MainActivity")
|
||||
Amber.isAppInForeground = true
|
||||
Amber.instance.setMainActivity(this)
|
||||
Amber.instance.startServiceFromUi()
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.greenart7c3.nostrsigner
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@@ -36,13 +35,13 @@ class MainViewModel(val context: Context) : ViewModel() {
|
||||
if (!userFromIntent.isNullOrBlank()) {
|
||||
if (userFromIntent.startsWith("npub")) {
|
||||
if (LocalPreferences.containsAccount(context, userFromIntent)) {
|
||||
Log.d(Amber.TAG, "getAccount: $userFromIntent")
|
||||
AmberLog.d(Amber.TAG, "getAccount: $userFromIntent")
|
||||
return userFromIntent
|
||||
}
|
||||
} else {
|
||||
val localNpub = Hex.decode(userFromIntent).toNpub()
|
||||
if (LocalPreferences.containsAccount(context, localNpub)) {
|
||||
Log.d(Amber.TAG, "getAccount: $localNpub")
|
||||
AmberLog.d(Amber.TAG, "getAccount: $localNpub")
|
||||
return localNpub
|
||||
}
|
||||
}
|
||||
@@ -60,36 +59,36 @@ class MainViewModel(val context: Context) : ViewModel() {
|
||||
|
||||
if (pubKeys.isEmpty()) {
|
||||
if (currentAccount != null && LocalPreferences.containsAccount(context, currentAccount)) {
|
||||
Log.d(Amber.TAG, "getAccount: $currentAccount")
|
||||
AmberLog.d(Amber.TAG, "getAccount: $currentAccount")
|
||||
return currentAccount
|
||||
}
|
||||
|
||||
val acc = LocalPreferences.allSavedAccounts(context).firstOrNull()
|
||||
if (acc != null) {
|
||||
Log.d(Amber.TAG, "getAccount: ${acc.npub}")
|
||||
AmberLog.d(Amber.TAG, "getAccount: ${acc.npub}")
|
||||
return acc.npub
|
||||
} else {
|
||||
Log.d(Amber.TAG, "getAccount: null")
|
||||
AmberLog.d(Amber.TAG, "getAccount: null")
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
val npub = Hex.decode(pubKeys.first()).toNpub()
|
||||
Log.d(Amber.TAG, "getAccount: $npub")
|
||||
AmberLog.d(Amber.TAG, "getAccount: $npub")
|
||||
return npub
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Error getting account", e)
|
||||
AmberLog.e(Amber.TAG, "Error getting account", e)
|
||||
if (currentAccount != null && LocalPreferences.containsAccount(context, currentAccount)) {
|
||||
Log.d(Amber.TAG, "getAccount: $currentAccount")
|
||||
AmberLog.d(Amber.TAG, "getAccount: $currentAccount")
|
||||
return currentAccount
|
||||
}
|
||||
|
||||
val acc = LocalPreferences.allSavedAccounts(context).firstOrNull()
|
||||
if (acc != null) {
|
||||
Log.d(Amber.TAG, "getAccount: ${acc.npub}")
|
||||
AmberLog.d(Amber.TAG, "getAccount: ${acc.npub}")
|
||||
return acc.npub
|
||||
} else {
|
||||
Log.d(Amber.TAG, "getAccount: null")
|
||||
AmberLog.d(Amber.TAG, "getAccount: null")
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -107,13 +106,13 @@ class MainViewModel(val context: Context) : ViewModel() {
|
||||
val currentAccount = LocalPreferences.currentAccount(context)
|
||||
if (currentAccount != null && npub != null && currentAccount != npub && npub.isNotBlank()) {
|
||||
if (npub.startsWith("npub")) {
|
||||
Log.d(Amber.TAG, "Switching account to $npub")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $npub")
|
||||
if (LocalPreferences.containsAccount(context, npub)) {
|
||||
accountStateViewModel?.switchUser(npub, Route.IncomingRequest.route)
|
||||
}
|
||||
} else {
|
||||
val localNpub = Hex.decode(npub).toNpub()
|
||||
Log.d(Amber.TAG, "Switching account to $localNpub")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $localNpub")
|
||||
if (LocalPreferences.containsAccount(context, localNpub)) {
|
||||
accountStateViewModel?.switchUser(localNpub, Route.IncomingRequest.route)
|
||||
}
|
||||
@@ -158,7 +157,7 @@ class MainViewModel(val context: Context) : ViewModel() {
|
||||
}
|
||||
error = false
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Error navigating to $route", e)
|
||||
AmberLog.e(Amber.TAG, "Error navigating to $route", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.os.Build
|
||||
import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyProperties
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.KeyStore
|
||||
import javax.crypto.Cipher
|
||||
@@ -82,7 +81,7 @@ object SecureCryptoHelper {
|
||||
keyGenerator.init(paramsBuilder.build())
|
||||
return keyGenerator.generateKey()
|
||||
} catch (e: Exception) {
|
||||
Log.w("SecureCryptoHelper", "StrongBox generation failed, falling back to TEE", e)
|
||||
AmberLog.w("SecureCryptoHelper", "StrongBox generation failed, falling back to TEE", e)
|
||||
paramsBuilder.setIsStrongBoxBacked(false)
|
||||
keyGenerator.init(paramsBuilder.build())
|
||||
return keyGenerator.generateKey()
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.greenart7c3.nostrsigner
|
||||
import android.content.Intent
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
@@ -58,7 +57,7 @@ class SignerActivity : AppCompatActivity() {
|
||||
lateinit var mainViewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.d(Amber.TAG, "onCreate SignerActivity")
|
||||
AmberLog.d(Amber.TAG, "onCreate SignerActivity")
|
||||
Amber.isAppInForeground = true
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -75,7 +74,7 @@ class SignerActivity : AppCompatActivity() {
|
||||
HttpClientManager.setDefaultUserAgent("Amber/${BuildConfig.VERSION_NAME}")
|
||||
|
||||
if (intent?.isLaunchFromHistory() == true) {
|
||||
Log.d(Amber.TAG, "Cleared intent history")
|
||||
AmberLog.d(Amber.TAG, "Cleared intent history")
|
||||
intent = Intent()
|
||||
}
|
||||
|
||||
@@ -161,13 +160,13 @@ class SignerActivity : AppCompatActivity() {
|
||||
val currentAccount = LocalPreferences.currentAccount(context)
|
||||
if (currentAccount != null && localNpub != null && currentAccount != localNpub && localNpub.isNotBlank()) {
|
||||
if (localNpub.startsWith("npub")) {
|
||||
Log.d(Amber.TAG, "Switching account to $localNpub")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $localNpub")
|
||||
if (LocalPreferences.containsAccount(context, localNpub)) {
|
||||
accountStateViewModel.switchUser(localNpub, Route.IncomingRequest.route)
|
||||
}
|
||||
} else {
|
||||
val localNpub2 = Hex.decode(localNpub).toNpub()
|
||||
Log.d(Amber.TAG, "Switching account to $localNpub2")
|
||||
AmberLog.d(Amber.TAG, "Switching account to $localNpub2")
|
||||
if (LocalPreferences.containsAccount(context, localNpub2)) {
|
||||
accountStateViewModel.switchUser(localNpub2, Route.IncomingRequest.route)
|
||||
}
|
||||
@@ -195,13 +194,13 @@ class SignerActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
Log.d(Amber.TAG, "onPause SignerActivity")
|
||||
AmberLog.d(Amber.TAG, "onPause SignerActivity")
|
||||
Amber.isAppInForeground = false
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
Log.d(Amber.TAG, "onResume SignerActivity")
|
||||
AmberLog.d(Amber.TAG, "onResume SignerActivity")
|
||||
Amber.isAppInForeground = true
|
||||
Amber.instance.setMainActivity(this)
|
||||
Amber.instance.startServiceFromUi()
|
||||
@@ -252,7 +251,7 @@ class SignerActivity : AppCompatActivity() {
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
Log.w(Amber.TAG, "Rate-limited intent from ${key.pkg} type=${key.type} kind=${key.kind}")
|
||||
AmberLog.w(Amber.TAG, "Rate-limited intent from ${key.pkg} type=${key.type} kind=${key.kind}")
|
||||
finishAndRemoveTask()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.ContentProvider
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
|
||||
class SignerProvider : ContentProvider() {
|
||||
override fun delete(
|
||||
@@ -31,7 +30,7 @@ class SignerProvider : ContentProvider() {
|
||||
): Cursor? {
|
||||
val ctx = context
|
||||
if (ctx == null) {
|
||||
Log.d(Amber.TAG, "No context")
|
||||
AmberLog.d(Amber.TAG, "No context")
|
||||
return null
|
||||
}
|
||||
// External apps are always attributed to their own Android package. The
|
||||
@@ -39,7 +38,7 @@ class SignerProvider : ContentProvider() {
|
||||
// caller-supplied query arguments, so an app cannot impersonate another one.
|
||||
val caller = callingPackage
|
||||
if (caller == null) {
|
||||
Log.d(Amber.TAG, "No calling package")
|
||||
AmberLog.d(Amber.TAG, "No calling package")
|
||||
return null
|
||||
}
|
||||
return SignerProviderQuery.query(
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.database.MatrixCursor
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.database.HistoryEntity
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -83,7 +82,7 @@ object SignerProviderQuery {
|
||||
operationUri: Uri,
|
||||
arguments: Array<String>?,
|
||||
): Cursor? {
|
||||
Log.d(Amber.TAG, "Querying $operationUri")
|
||||
AmberLog.d(Amber.TAG, "Querying $operationUri")
|
||||
|
||||
val appId = BuildConfig.APPLICATION_ID
|
||||
val uriString = operationUri.toString()
|
||||
@@ -92,24 +91,24 @@ object SignerProviderQuery {
|
||||
"content://$appId.SIGN_EVENT" -> {
|
||||
val json = arguments?.first()
|
||||
if (json == null) {
|
||||
Log.d(Amber.TAG, "No json")
|
||||
AmberLog.d(Amber.TAG, "No json")
|
||||
return null
|
||||
}
|
||||
val npub = IntentUtils.parsePubKey(arguments[2])
|
||||
if (npub == null) {
|
||||
Log.d(Amber.TAG, "No npub")
|
||||
AmberLog.d(Amber.TAG, "No npub")
|
||||
return null
|
||||
}
|
||||
val account = LocalPreferences.loadFromEncryptedStorageSync(context, npub)
|
||||
if (account == null) {
|
||||
Log.d(Amber.TAG, "No account from storage")
|
||||
AmberLog.d(Amber.TAG, "No account from storage")
|
||||
return null
|
||||
}
|
||||
captureCallerMetadata(context, callerPackageName, account)
|
||||
val event = try {
|
||||
IntentUtils.getUnsignedEvent(json, account)
|
||||
} catch (e: Exception) {
|
||||
Log.d(Amber.TAG, "Failed to parse event from $requesterId", e)
|
||||
AmberLog.d(Amber.TAG, "Failed to parse event from $requesterId", e)
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -285,7 +284,7 @@ object SignerProviderQuery {
|
||||
val scopeStr = arguments.getOrNull(4) ?: ""
|
||||
val parsedKind = kindStr?.toIntOrNull()
|
||||
if (parsedKind == null) {
|
||||
Log.d(Amber.TAG, "NIP-44 v3 request missing/invalid kind")
|
||||
AmberLog.d(Amber.TAG, "NIP-44 v3 request missing/invalid kind")
|
||||
return rejectedCursor()
|
||||
}
|
||||
parsedKind to scopeStr
|
||||
@@ -453,17 +452,17 @@ object SignerProviderQuery {
|
||||
"content://$appId.SIGN_PSBT" -> {
|
||||
val psbtHex = arguments?.first()
|
||||
if (psbtHex == null) {
|
||||
Log.d(Amber.TAG, "No psbt")
|
||||
AmberLog.d(Amber.TAG, "No psbt")
|
||||
return null
|
||||
}
|
||||
val npub = IntentUtils.parsePubKey(arguments[2])
|
||||
if (npub == null) {
|
||||
Log.d(Amber.TAG, "No npub")
|
||||
AmberLog.d(Amber.TAG, "No npub")
|
||||
return null
|
||||
}
|
||||
val account = LocalPreferences.loadFromEncryptedStorageSync(context, npub)
|
||||
if (account == null) {
|
||||
Log.d(Amber.TAG, "No account from storage")
|
||||
AmberLog.d(Amber.TAG, "No account from storage")
|
||||
return null
|
||||
}
|
||||
captureCallerMetadata(context, callerPackageName, account)
|
||||
@@ -505,7 +504,7 @@ object SignerProviderQuery {
|
||||
val result = try {
|
||||
runBlocking { account.signPsbt(psbtHex) }
|
||||
} catch (e: Exception) {
|
||||
Log.d(Amber.TAG, "Failed to sign psbt", e)
|
||||
AmberLog.d(Amber.TAG, "Failed to sign psbt", e)
|
||||
scope.launch {
|
||||
val logDb = Amber.instance.getLogDatabase(account.npub)
|
||||
logDb.dao().insertLog(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.greenart7c3.nostrsigner.database
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
@@ -9,6 +8,7 @@ import androidx.room.TypeConverters
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
val MIGRATION_1_2 =
|
||||
@@ -110,7 +110,7 @@ val MIGRATION_11_12 = object : Migration(11, 12) {
|
||||
try {
|
||||
db.execSQL("DROP TABLE notification")
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "No notification table", e)
|
||||
AmberLog.e(Amber.TAG, "No notification table", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ val MIGRATION_12_13 = object : Migration(12, 13) {
|
||||
try {
|
||||
db.execSQL("DROP TABLE history")
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "No history table", e)
|
||||
AmberLog.e(Amber.TAG, "No history table", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ val MIGRATION_14_15 = object : Migration(14, 15) {
|
||||
try {
|
||||
db.execSQL("DROP TABLE amber_log")
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "No amber_log table", e)
|
||||
AmberLog.e(Amber.TAG, "No amber_log table", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ val MIGRATION_15_16 = object : Migration(15, 16) {
|
||||
try {
|
||||
db.execSQL("DROP TABLE history2")
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "No amber_log table", e)
|
||||
AmberLog.e(Amber.TAG, "No amber_log table", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.greenart7c3.nostrsigner.database
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.paging.PagingSource
|
||||
@@ -11,6 +10,7 @@ import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -124,7 +124,7 @@ interface HistoryDao {
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Error adding history", e)
|
||||
AmberLog.e(Amber.TAG, "Error adding history", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.greenart7c3.nostrsigner.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.vitorpamplona.quartz.utils.ciphers.AESGCM
|
||||
import com.vitorpamplona.quartz.utils.ciphers.NostrCipher
|
||||
import okhttp3.Interceptor
|
||||
@@ -40,7 +40,7 @@ class EncryptedBlobInterceptor(
|
||||
private fun Response.decryptOrNull(cipher: NostrCipher): Response? = try {
|
||||
decrypt(cipher)
|
||||
} catch (e: Exception) {
|
||||
Log.w("EncryptedBlobInterceptor", "Failed to decrypt", e)
|
||||
AmberLog.w("EncryptedBlobInterceptor", "Failed to decrypt", e)
|
||||
null
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
package com.greenart7c3.nostrsigner.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
import java.time.Duration
|
||||
@@ -65,7 +65,7 @@ object HttpClientManager {
|
||||
|
||||
private fun setDefaultProxy(proxy: Proxy?) {
|
||||
if (currentProxy != proxy) {
|
||||
Log.d(Amber.TAG, "Changing proxy to: ${proxy != null}")
|
||||
AmberLog.d(Amber.TAG, "Changing proxy to: ${proxy != null}")
|
||||
currentProxy = proxy
|
||||
|
||||
// Invalidate so the proxied client is rebuilt lazily on the next
|
||||
@@ -78,7 +78,7 @@ object HttpClientManager {
|
||||
}
|
||||
|
||||
fun setDefaultTimeout(timeout: Duration) {
|
||||
Log.d(Amber.TAG, "Changing timeout to: $timeout")
|
||||
AmberLog.d(Amber.TAG, "Changing timeout to: $timeout")
|
||||
if (defaultTimeout.seconds != timeout.seconds) {
|
||||
defaultTimeout = timeout
|
||||
|
||||
@@ -89,7 +89,7 @@ object HttpClientManager {
|
||||
}
|
||||
|
||||
fun setDefaultUserAgent(userAgentHeader: String) {
|
||||
Log.d(Amber.TAG, "Changing userAgent")
|
||||
AmberLog.d(Amber.TAG, "Changing userAgent")
|
||||
if (userAgent != userAgentHeader) {
|
||||
userAgent = userAgentHeader
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
package com.greenart7c3.nostrsigner.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import java.net.InetSocketAddress
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Request
|
||||
@@ -42,7 +42,7 @@ class LoggingInterceptor : Interceptor {
|
||||
val response: Response = chain.proceed(request)
|
||||
val t2 = System.nanoTime()
|
||||
|
||||
Log.d(Amber.TAG, "Req $port ${request.url} in ${(t2 - t1) / 1e6}ms")
|
||||
AmberLog.d(Amber.TAG, "Req $port ${request.url} in ${(t2 - t1) / 1e6}ms")
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationChannelCompat
|
||||
import androidx.core.app.NotificationChannelGroupCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.MainActivity
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
@@ -53,7 +53,7 @@ class AmberRelayStats(
|
||||
client.availableRelaysFlow().value,
|
||||
false,
|
||||
)?.let { notification ->
|
||||
Log.d(Amber.TAG, "updateNotification")
|
||||
AmberLog.d(Amber.TAG, "updateNotification")
|
||||
notificationManager.notify(2, notification)
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ class AmberRelayStats(
|
||||
): Notification? {
|
||||
try {
|
||||
if (available.isEmpty() && connected.isEmpty() && !Amber.instance.settings.killSwitch.value) {
|
||||
Log.d(Amber.TAG, "No relays available, removing relay notification")
|
||||
AmberLog.d(Amber.TAG, "No relays available, removing relay notification")
|
||||
val notificationManager = NotificationManagerCompat.from(appContext)
|
||||
notificationManager.cancel(2)
|
||||
return null
|
||||
@@ -230,7 +230,7 @@ class AmberRelayStats(
|
||||
|
||||
return notificationBuilder.build()
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "failed to create notification", e)
|
||||
AmberLog.e(Amber.TAG, "failed to create notification", e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,7 @@ class AmberRelayStats(
|
||||
connected,
|
||||
available,
|
||||
)?.let {
|
||||
Log.d(Amber.TAG, "updateNotification")
|
||||
AmberLog.d(Amber.TAG, "updateNotification")
|
||||
notificationManager.notify(2, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@ package com.greenart7c3.nostrsigner.relays
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
@@ -63,9 +62,7 @@ class NostrClientLoggerListener(
|
||||
// successful connection (onConnected) or a network change / manual reconnect.
|
||||
private fun scheduleReconnect(relay: NormalizedRelayUrl) {
|
||||
if (!RelayHealthTracker.recordFailure(relay)) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(Amber.TAG, "Relay ${relay.url} marked dead; skipping reconnect")
|
||||
}
|
||||
AmberLog.d(Amber.TAG, "Relay ${relay.url} marked dead; skipping reconnect")
|
||||
return
|
||||
}
|
||||
reconnectWithBackoff()
|
||||
@@ -80,7 +77,7 @@ class NostrClientLoggerListener(
|
||||
|
||||
reconnectJob?.cancel()
|
||||
reconnectJob = scope.launch {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "Reconnecting in ${reconnectDelay / 1000}s...")
|
||||
AmberLog.d(Amber.TAG, "Reconnecting in ${reconnectDelay / 1000}s...")
|
||||
delay(reconnectDelay)
|
||||
reconnectDelay = (reconnectDelay * 2).coerceAtMost(60_000L)
|
||||
if (!BuildFlavorChecker.isOfflineFlavor() && !Amber.instance.settings.killSwitch.value) {
|
||||
@@ -123,7 +120,7 @@ class NostrClientLoggerListener(
|
||||
}
|
||||
|
||||
override fun onCannotConnect(relay: IRelayClient, errorMessage: String) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onCannotConnect: ${relay.url.url} error: $errorMessage")
|
||||
AmberLog.d(Amber.TAG, "onCannotConnect: ${relay.url.url} error: $errorMessage")
|
||||
saveLog(relay.url.url, "onCannotConnect", errorMessage)
|
||||
|
||||
if (System.currentTimeMillis() - Amber.instance.intentionalDisconnectTime < 2_000) {
|
||||
@@ -136,7 +133,7 @@ class NostrClientLoggerListener(
|
||||
}
|
||||
|
||||
override fun onSent(relay: IRelayClient, cmdStr: String, cmd: Command, success: Boolean) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onSent: ${relay.url.url} success: $success cmd: $cmdStr")
|
||||
AmberLog.d(Amber.TAG, "onSent: ${relay.url.url} success: $success cmd: $cmdStr")
|
||||
|
||||
if (cmd is ReqCmd) {
|
||||
saveLog(relay.url.url, "onSent", "Subscribed to relay: $success")
|
||||
@@ -159,7 +156,7 @@ class NostrClientLoggerListener(
|
||||
}
|
||||
|
||||
override fun onIncomingMessage(relay: IRelayClient, msgStr: String, msg: Message) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onIncomingMessage: ${relay.url.url} msg: $msgStr")
|
||||
AmberLog.d(Amber.TAG, "onIncomingMessage: ${relay.url.url} msg: $msgStr")
|
||||
|
||||
if (msg is OkMessage) {
|
||||
saveLog(relay.url.url, "onIncomingMessage", "Relay accepted message: ${msg.success}")
|
||||
@@ -173,11 +170,11 @@ class NostrClientLoggerListener(
|
||||
}
|
||||
|
||||
override fun onDisconnected(relay: IRelayClient) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onDisconnected: ${relay.url.url}")
|
||||
AmberLog.d(Amber.TAG, "onDisconnected: ${relay.url.url}")
|
||||
saveLog(relay.url.url, "onDisconnected", "Disconnected")
|
||||
|
||||
if (System.currentTimeMillis() - Amber.instance.intentionalDisconnectTime < 2_000) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onDisconnected: ${relay.url.url} intentional, skipping reconnect")
|
||||
AmberLog.d(Amber.TAG, "onDisconnected: ${relay.url.url} intentional, skipping reconnect")
|
||||
super.onDisconnected(relay)
|
||||
return
|
||||
}
|
||||
@@ -187,13 +184,13 @@ class NostrClientLoggerListener(
|
||||
}
|
||||
|
||||
override fun onConnecting(relay: IRelayClient) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onConnecting: ${relay.url.url}")
|
||||
AmberLog.d(Amber.TAG, "onConnecting: ${relay.url.url}")
|
||||
saveLog(relay.url.url, "onConnecting", "Connecting")
|
||||
super.onConnecting(relay)
|
||||
}
|
||||
|
||||
override fun onConnected(relay: IRelayClient, pingMillis: Int, compressed: Boolean) {
|
||||
if (BuildConfig.DEBUG) Log.d(Amber.TAG, "onConnected: ${relay.url.url} ping: ${pingMillis}ms compressed: $compressed")
|
||||
AmberLog.d(Amber.TAG, "onConnected: ${relay.url.url} ping: ${pingMillis}ms compressed: $compressed")
|
||||
saveLog(relay.url.url, "onConnected", "Connected")
|
||||
// Relay recovered: clear its failure streak so it is eligible for the
|
||||
// normal reconnect-with-backoff path (and the subscription) again.
|
||||
|
||||
@@ -2,11 +2,11 @@ package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.anggrayudi.storage.extension.toDocumentFile
|
||||
import com.anggrayudi.storage.file.openInputStream
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -68,7 +68,7 @@ object AccountExportService {
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
|
||||
Log.e("Amber", "Error importing account", e)
|
||||
AmberLog.e("Amber", "Error importing account", e)
|
||||
}
|
||||
}
|
||||
onFinish()
|
||||
@@ -137,7 +137,7 @@ object AccountExportService {
|
||||
LocalPreferences.updatePrefsForLogin(Amber.instance, account, hexKey.toHexKey(), privKey, null)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e("Amber", "Error importing ncryptsec at index $index", e)
|
||||
AmberLog.e("Amber", "Error importing ncryptsec at index $index", e)
|
||||
}
|
||||
}
|
||||
onFinish()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.util.Log
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationEntity
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationPermissionsEntity
|
||||
@@ -185,7 +185,7 @@ object ApplicationBackup {
|
||||
delay(INBOX_FETCH_TIMEOUT_MS)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.w(Amber.TAG, "ApplicationBackup: inbox relay fetch failed", e)
|
||||
AmberLog.w(Amber.TAG, "ApplicationBackup: inbox relay fetch failed", e)
|
||||
} finally {
|
||||
runCatching { client.unsubscribe(subId) }
|
||||
client.removeConnectionListener(listener)
|
||||
@@ -212,7 +212,7 @@ object ApplicationBackup {
|
||||
try {
|
||||
val payload = buildPayload(npub, account)
|
||||
if (payload.applications.isEmpty()) {
|
||||
Log.d(Amber.TAG, "ApplicationBackup: no applications to backup for $npub, skipping")
|
||||
AmberLog.d(Amber.TAG, "ApplicationBackup: no applications to backup for $npub, skipping")
|
||||
return true
|
||||
}
|
||||
val json = toJson(payload)
|
||||
@@ -228,15 +228,15 @@ object ApplicationBackup {
|
||||
)
|
||||
val relays = resolveWriteRelays(account)
|
||||
if (relays.isEmpty()) {
|
||||
Log.w(Amber.TAG, "ApplicationBackup: no relays resolved for backup")
|
||||
AmberLog.w(Amber.TAG, "ApplicationBackup: no relays resolved for backup")
|
||||
return false
|
||||
}
|
||||
val ok = Amber.instance.client.publishAndConfirm(event, relays)
|
||||
Log.d(Amber.TAG, "ApplicationBackup: publish for $npub result=$ok relays=${relays.size}")
|
||||
AmberLog.d(Amber.TAG, "ApplicationBackup: publish for $npub result=$ok relays=${relays.size}")
|
||||
return ok
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "ApplicationBackup: failed to publish backup for $npub", e)
|
||||
AmberLog.e(Amber.TAG, "ApplicationBackup: failed to publish backup for $npub", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,7 @@ object ApplicationBackup {
|
||||
delay(BACKUP_FETCH_TIMEOUT_MS)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "ApplicationBackup: failed to fetch backup event", e)
|
||||
AmberLog.e(Amber.TAG, "ApplicationBackup: failed to fetch backup event", e)
|
||||
} finally {
|
||||
runCatching { client.unsubscribe(subId) }
|
||||
client.removeConnectionListener(listener)
|
||||
@@ -291,7 +291,7 @@ object ApplicationBackup {
|
||||
fromJson(json)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "ApplicationBackup: failed to decrypt/parse backup payload", e)
|
||||
AmberLog.e(Amber.TAG, "ApplicationBackup: failed to decrypt/parse backup payload", e)
|
||||
null
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ object ApplicationBackup {
|
||||
RestoreResult.Success(apps, permissions)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "ApplicationBackup: failed to restore payload for $npub", e)
|
||||
AmberLog.e(Amber.TAG, "ApplicationBackup: failed to restore payload for $npub", e)
|
||||
RestoreResult.Failed(e.message ?: "Unknown error")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
@@ -21,7 +21,7 @@ class BackupApplicationsWorker(appContext: Context, workerParams: WorkerParamete
|
||||
ApplicationBackup.publishBackup(info.npub, account)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "BackupApplicationsWorker: failed for ${info.npub}", e)
|
||||
AmberLog.e(Amber.TAG, "BackupApplicationsWorker: failed for ${info.npub}", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.greenart7c3.nostrsigner.service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -16,19 +16,19 @@ class BootReceiver : BroadcastReceiver() {
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (BuildFlavorChecker.isOfflineFlavor()) return
|
||||
Log.d(Amber.TAG, "Received intent: ${intent.action}")
|
||||
AmberLog.d(Amber.TAG, "Received intent: ${intent.action}")
|
||||
|
||||
when (intent.action) {
|
||||
Intent.ACTION_MY_PACKAGE_REPLACED,
|
||||
Intent.ACTION_BOOT_COMPLETED,
|
||||
-> {
|
||||
Log.d(Amber.TAG, "Received ${intent.action}")
|
||||
AmberLog.d(Amber.TAG, "Received ${intent.action}")
|
||||
scope.launch {
|
||||
val shouldStartService = LocalPreferences.getStartServiceOnBoot(context)
|
||||
if (intent.action == Intent.ACTION_BOOT_COMPLETED &&
|
||||
!shouldStartService
|
||||
) {
|
||||
Log.d(Amber.TAG, "Skipping service start on boot (disabled in settings)")
|
||||
AmberLog.d(Amber.TAG, "Skipping service start on boot (disabled in settings)")
|
||||
return@launch
|
||||
}
|
||||
Amber.instance.startService()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.SignerActivity
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationEntity
|
||||
@@ -164,7 +164,7 @@ object BunkerRequestUtils {
|
||||
encryptedContent,
|
||||
)
|
||||
|
||||
Log.d(Amber.TAG, "Sending response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
AmberLog.d(Amber.TAG, "Sending response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
|
||||
val success = retryWithBackoff {
|
||||
val result = Amber.instance.client.publishAndConfirm(
|
||||
@@ -197,12 +197,12 @@ object BunkerRequestUtils {
|
||||
}
|
||||
|
||||
if (success) {
|
||||
Log.d(Amber.TAG, "Success response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
AmberLog.d(Amber.TAG, "Success response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
onDone(true)
|
||||
} else {
|
||||
onDone(false)
|
||||
AmberListenerSingleton.showErrorMessage()
|
||||
Log.d(Amber.TAG, "Failed response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
AmberLog.d(Amber.TAG, "Failed response to relays ${relays.map { relay -> relay.url }} type ${bunkerRequest.request.method}")
|
||||
}
|
||||
onLoading(false)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -28,11 +28,11 @@ class ClearLogsWorker(appContext: Context, workerParams: WorkerParameters) : Cor
|
||||
|
||||
val deletedHistory = historyDao.deleteOldHistory(oneWeekAgo)
|
||||
if (deletedHistory > 0) {
|
||||
Log.d(Amber.TAG, "Deleted $deletedHistory old history entries")
|
||||
AmberLog.d(Amber.TAG, "Deleted $deletedHistory old history entries")
|
||||
}
|
||||
val excessHistory = historyDao.deleteExcessHistory(MAX_HISTORY_ENTRIES)
|
||||
if (excessHistory > 0) {
|
||||
Log.d(Amber.TAG, "Trimmed $excessHistory excess history entries (cap: $MAX_HISTORY_ENTRIES)")
|
||||
AmberLog.d(Amber.TAG, "Trimmed $excessHistory excess history entries (cap: $MAX_HISTORY_ENTRIES)")
|
||||
}
|
||||
|
||||
val logDatabase = Amber.instance.getLogDatabase(it.npub)
|
||||
@@ -40,11 +40,11 @@ class ClearLogsWorker(appContext: Context, workerParams: WorkerParameters) : Cor
|
||||
|
||||
val deletedLogs = logDao.deleteOldLog(threeDaysAgo)
|
||||
if (deletedLogs > 0) {
|
||||
Log.d(Amber.TAG, "Deleted $deletedLogs old log entries")
|
||||
AmberLog.d(Amber.TAG, "Deleted $deletedLogs old log entries")
|
||||
}
|
||||
val excessLogs = logDao.deleteExcessLogs(MAX_LOG_ENTRIES)
|
||||
if (excessLogs > 0) {
|
||||
Log.d(Amber.TAG, "Trimmed $excessLogs excess log entries (cap: $MAX_LOG_ENTRIES)")
|
||||
AmberLog.d(Amber.TAG, "Trimmed $excessLogs excess log entries (cap: $MAX_LOG_ENTRIES)")
|
||||
}
|
||||
|
||||
val dao = Amber.instance.dao(it.npub)
|
||||
@@ -63,7 +63,7 @@ class ClearLogsWorker(appContext: Context, workerParams: WorkerParameters) : Cor
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "Error in ClearLogsWorker", e)
|
||||
AmberLog.e(Amber.TAG, "Error in ClearLogsWorker", e)
|
||||
}
|
||||
}
|
||||
return Result.success()
|
||||
|
||||
@@ -8,9 +8,9 @@ import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.core.app.ServiceCompat
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
@@ -68,7 +68,7 @@ class ConnectivityService : Service() {
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
Log.d(
|
||||
AmberLog.d(
|
||||
"ServiceManager NetworkCallback",
|
||||
"onCapabilitiesChanged: ${network.networkHandle} hasMobileData ${Amber.instance.isOnMobileDataState.value} hasWifi ${Amber.instance.isOnWifiDataState.value}",
|
||||
)
|
||||
@@ -98,7 +98,7 @@ class ConnectivityService : Service() {
|
||||
override fun onBind(intent: Intent): IBinder? = null
|
||||
|
||||
override fun onCreate() {
|
||||
Log.d(Amber.TAG, "onCreate ConnectivityService")
|
||||
AmberLog.d(Amber.TAG, "onCreate ConnectivityService")
|
||||
|
||||
if (!BuildFlavorChecker.isOfflineFlavor()) {
|
||||
TorManager.init(this)
|
||||
@@ -174,19 +174,19 @@ class ConnectivityService : Service() {
|
||||
timer.cancel()
|
||||
if (!BuildFlavorChecker.isOfflineFlavor()) {
|
||||
try {
|
||||
Log.d(Amber.TAG, "unregisterNetworkCallback")
|
||||
AmberLog.d(Amber.TAG, "unregisterNetworkCallback")
|
||||
val connectivityManager =
|
||||
(getSystemService(ConnectivityManager::class.java) as ConnectivityManager)
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
} catch (e: Exception) {
|
||||
Log.d(Amber.TAG, "Failed to unregisterNetworkCallback", e)
|
||||
AmberLog.d(Amber.TAG, "Failed to unregisterNetworkCallback", e)
|
||||
}
|
||||
}
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Log.d(Amber.TAG, "onStartCommand")
|
||||
AmberLog.d(Amber.TAG, "onStartCommand")
|
||||
val foregroundServiceType =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
|
||||
@@ -203,7 +203,7 @@ class ConnectivityService : Service() {
|
||||
} catch (e: Exception) {
|
||||
// Android 12+ can refuse a background FGS start with ForegroundServiceStartNotAllowedException;
|
||||
// swallow it and let the next foreground start (startServiceFromUi) retry.
|
||||
Log.e(Amber.TAG, "Failed to start ConnectivityService in foreground", e)
|
||||
AmberLog.e(Amber.TAG, "Failed to start ConnectivityService in foreground", e)
|
||||
stopSelf(startId)
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
@@ -76,7 +76,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
url: String,
|
||||
npub: String? = null,
|
||||
) {
|
||||
Log.d(Amber.TAG, "$url: $text")
|
||||
AmberLog.d(Amber.TAG, "$url: $text")
|
||||
Amber.instance.applicationIOScope.launch {
|
||||
if (npub != null) {
|
||||
val dao = Amber.instance.getLogDatabase(npub).dao()
|
||||
|
||||
@@ -6,13 +6,13 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Browser
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.Clipboard
|
||||
import androidx.core.net.toUri
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.FailedMigrationException
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
@@ -635,7 +635,7 @@ object IntentUtils {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
AmberLog.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
ClearTextEncryptedDataKind(data, result)
|
||||
}
|
||||
} else if (data.startsWith("[")) {
|
||||
@@ -643,7 +643,7 @@ object IntentUtils {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(data)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
AmberLog.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
ClearTextEncryptedDataKind(data, result)
|
||||
}
|
||||
} else {
|
||||
@@ -667,7 +667,7 @@ object IntentUtils {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(decryptedSealData)
|
||||
EventEncryptedDataKind(event, TagArrayEncryptedDataKind(tagArray, decryptedSealData), decryptedSealData)
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
AmberLog.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
EventEncryptedDataKind(event, ClearTextEncryptedDataKind(event.content, decryptedSealData), result)
|
||||
}
|
||||
} else {
|
||||
@@ -677,7 +677,7 @@ object IntentUtils {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
AmberLog.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
ClearTextEncryptedDataKind(data, result)
|
||||
}
|
||||
} else if (result.startsWith("[")) {
|
||||
@@ -685,7 +685,7 @@ object IntentUtils {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(result)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
AmberLog.e("IntentUtils", "Error parsing TagArray: ${e.message}")
|
||||
ClearTextEncryptedDataKind(data, result)
|
||||
}
|
||||
} else {
|
||||
@@ -751,7 +751,7 @@ object IntentUtils {
|
||||
return getIntentDataWithoutExtras(context, intent.data?.toString() ?: "", intent, packageName, route, localAccount)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Error parsing intent: ${e.message}", e)
|
||||
AmberLog.e(Amber.TAG, "Error parsing intent: ${e.message}", e)
|
||||
emitInvalid(intent, packageName, "Error parsing intent: ${e.message}", e)
|
||||
Amber.instance.applicationIOScope.launch {
|
||||
LocalPreferences.allSavedAccounts(Amber.instance).forEach {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
@@ -157,7 +157,7 @@ object NostrConnectUtils {
|
||||
),
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, e.message, e)
|
||||
AmberLog.e(Amber.TAG, e.message, e)
|
||||
Amber.instance.applicationIOScope.launch {
|
||||
Amber.instance.getLogDatabase(account.npub).dao().insertLog(
|
||||
LogEntity(
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.relays.RelayHealthTracker
|
||||
@@ -62,7 +62,7 @@ class NotificationSubscription(
|
||||
}
|
||||
|
||||
override fun onSent(relay: IRelayClient, cmdStr: String, cmd: Command, success: Boolean) {
|
||||
Log.d("NotificationSubscription", "onSend: ${relay.url}, $cmdStr, $success")
|
||||
AmberLog.d("NotificationSubscription", "onSend: ${relay.url}, $cmdStr, $success")
|
||||
super.onSent(relay, cmdStr, cmd, success)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,25 +4,25 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Process
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class StopServiceReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Log.d(Amber.TAG, "StopServiceReceiver: stopping service and killing process")
|
||||
AmberLog.d(Amber.TAG, "StopServiceReceiver: stopping service and killing process")
|
||||
|
||||
try {
|
||||
Amber.instance.client.disconnect()
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Failed to disconnect client on stop", e)
|
||||
AmberLog.e(Amber.TAG, "Failed to disconnect client on stop", e)
|
||||
}
|
||||
|
||||
try {
|
||||
context.stopService(Intent(context, ConnectivityService::class.java))
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Failed to stop ConnectivityService", e)
|
||||
AmberLog.e(Amber.TAG, "Failed to stop ConnectivityService", e)
|
||||
}
|
||||
|
||||
val notificationManager = NotificationManagerCompat.from(context)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.util.Log
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.models.TorMode
|
||||
import com.greenart7c3.nostrsigner.okhttp.HttpClientManager
|
||||
@@ -73,7 +73,7 @@ object TrustScoreService {
|
||||
try {
|
||||
getScore(url)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error prefetching score for $url", e)
|
||||
AmberLog.e(TAG, "Error prefetching score for $url", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ object TrustScoreService {
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
if (!response.isSuccessful) {
|
||||
Log.w(TAG, "Failed to fetch trust score for $relayUrl: ${response.code}")
|
||||
AmberLog.w(TAG, "Failed to fetch trust score for $relayUrl: ${response.code}")
|
||||
cacheResult(normalizedUrl, null, isFailed = true)
|
||||
return@withContext null
|
||||
}
|
||||
@@ -117,7 +117,7 @@ object TrustScoreService {
|
||||
cacheResult(normalizedUrl, score, isFailed = false)
|
||||
score
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error fetching trust score for $relayUrl", e)
|
||||
AmberLog.e(TAG, "Error fetching trust score for $relayUrl", e)
|
||||
val normalizedUrl = normalizeUrl(relayUrl)
|
||||
cacheResult(normalizedUrl, null, isFailed = true)
|
||||
null
|
||||
@@ -134,7 +134,7 @@ object TrustScoreService {
|
||||
}
|
||||
json.get("data")?.get("score")?.asInt()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error parsing trust score response", e)
|
||||
AmberLog.e(TAG, "Error parsing trust score response", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
@@ -35,7 +35,7 @@ class UpdateCheckWorker(appContext: Context, workerParams: WorkerParameters) : C
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "UpdateCheckWorker: error checking for updates", e)
|
||||
AmberLog.e(Amber.TAG, "UpdateCheckWorker: error checking for updates", e)
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.greenart7c3.nostrsigner.service
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
@@ -120,23 +120,23 @@ class ZapstoreUpdater(
|
||||
LocalPreferences.loadSettingsFromEncryptedStorage()
|
||||
}
|
||||
if (settings.updateChannel == UpdateChannel.STABLE) {
|
||||
Log.d("zapstore", "zapstore relay")
|
||||
AmberLog.d("zapstore", "zapstore relay")
|
||||
client.subscribe(releaseSubId, listOf(updateRelays.first()).associateWith { listOf(releaseFilter) })
|
||||
} else {
|
||||
Log.d("zapstore", "other relays")
|
||||
AmberLog.d("zapstore", "other relays")
|
||||
client.subscribe(releaseSubId, updateRelays.drop(1).associateWith { listOf(releaseFilter) })
|
||||
}
|
||||
|
||||
timeoutJob = scope.launch {
|
||||
delay(EOSE_TIMEOUT_MS)
|
||||
Log.w(Amber.TAG, "ZapstoreUpdater: timeout waiting for EOSE")
|
||||
AmberLog.w(Amber.TAG, "ZapstoreUpdater: timeout waiting for EOSE")
|
||||
onReleaseEose()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun processReleaseEvent(event: Event) {
|
||||
if (!event.verify()) {
|
||||
Log.w(Amber.TAG, "ZapstoreUpdater: invalid release event: ${event.toJson()}")
|
||||
AmberLog.w(Amber.TAG, "ZapstoreUpdater: invalid release event: ${event.toJson()}")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class ZapstoreUpdater(
|
||||
val version = tags.firstOrNull { it.size > 1 && it[0] == "version" }?.getOrNull(1) ?: return
|
||||
if (!isNewerVersion(version)) return
|
||||
|
||||
Log.d(Amber.TAG, "ZapstoreUpdater: found release $version (current: ${BuildConfig.VERSION_NAME})")
|
||||
AmberLog.d(Amber.TAG, "ZapstoreUpdater: found release $version (current: ${BuildConfig.VERSION_NAME})")
|
||||
|
||||
// Try direct URL first (some release events include it)
|
||||
val directUrl = tags.firstOrNull { it.size > 1 && it[0] == "url" }?.getOrNull(1)
|
||||
@@ -199,7 +199,7 @@ class ZapstoreUpdater(
|
||||
|
||||
private fun processFileEvent(event: Event) {
|
||||
if (!event.verify()) {
|
||||
Log.w(Amber.TAG, "ZapstoreUpdater: invalid file event: ${event.toJson()}")
|
||||
AmberLog.w(Amber.TAG, "ZapstoreUpdater: invalid file event: ${event.toJson()}")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ class ZapstoreUpdater(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "ZapstoreUpdater: download failed", e)
|
||||
AmberLog.e(Amber.TAG, "ZapstoreUpdater: download failed", e)
|
||||
downloadState.value = DownloadState.ERROR
|
||||
}
|
||||
}
|
||||
@@ -284,7 +284,7 @@ class ZapstoreUpdater(
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
if (!response.isSuccessful) {
|
||||
Log.e(Amber.TAG, "ZapstoreUpdater: HTTP ${response.code} for ${release.url}")
|
||||
AmberLog.e(Amber.TAG, "ZapstoreUpdater: HTTP ${response.code} for ${release.url}")
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -314,11 +314,11 @@ class ZapstoreUpdater(
|
||||
val actualHash = digest.digest().joinToString("") { "%02x".format(it) }
|
||||
val expectedHash = release.hash.removePrefix("sha256:")
|
||||
if (!actualHash.equals(expectedHash, ignoreCase = true)) {
|
||||
Log.e(Amber.TAG, "ZapstoreUpdater: hash mismatch! expected=$expectedHash actual=$actualHash")
|
||||
AmberLog.e(Amber.TAG, "ZapstoreUpdater: hash mismatch! expected=$expectedHash actual=$actualHash")
|
||||
apkFile.delete()
|
||||
return null
|
||||
}
|
||||
Log.d(Amber.TAG, "ZapstoreUpdater: hash verified OK")
|
||||
AmberLog.d(Amber.TAG, "ZapstoreUpdater: hash verified OK")
|
||||
}
|
||||
|
||||
return apkFile
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -192,7 +192,7 @@ class AccountStateViewModel(npub: String?) : ViewModel() {
|
||||
observerJob?.cancel()
|
||||
observerJob = Amber.instance.applicationIOScope.launch(Dispatchers.IO) {
|
||||
account.saveable.collect {
|
||||
Log.d(Amber.TAG, "Account saved")
|
||||
AmberLog.d(Amber.TAG, "Account saved")
|
||||
LocalPreferences.saveToEncryptedStorage(Amber.instance, it.account, null, null, null)
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ class AccountStateViewModel(npub: String?) : ViewModel() {
|
||||
restorePrompt.value = RestorePromptState.Found(account, payload, event.createdAt)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "maybeOfferRestore: failed", e)
|
||||
AmberLog.e(Amber.TAG, "maybeOfferRestore: failed", e)
|
||||
restorePrompt.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -48,6 +47,7 @@ import androidx.paging.PagingConfig
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import androidx.paging.compose.itemKey
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.database.HistoryEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -174,11 +174,11 @@ fun ActivitiesScreen(
|
||||
lazyPagingItems.apply {
|
||||
when (loadState.refresh) {
|
||||
is LoadState.Loading -> item {
|
||||
Log.d("ActivitiesScreen", "Loading...")
|
||||
AmberLog.d("ActivitiesScreen", "Loading...")
|
||||
Text("Loading...", Modifier.padding(16.dp))
|
||||
}
|
||||
is LoadState.Error -> item {
|
||||
Log.d("ActivitiesScreen", "Error loading data")
|
||||
AmberLog.d("ActivitiesScreen", "Error loading data")
|
||||
Text("Error loading data", Modifier.padding(16.dp))
|
||||
}
|
||||
is LoadState.NotLoading -> { }
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -41,6 +40,7 @@ import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -185,7 +185,7 @@ fun ApplicationsScreen(
|
||||
runCatching {
|
||||
navController.navigate("Permission/${applicationWithHistory.key}")
|
||||
}.onFailure {
|
||||
Log.e("ApplicationsScreen", "Failed to open permissions for ${applicationWithHistory.key}", it)
|
||||
AmberLog.e("ApplicationsScreen", "Failed to open permissions for ${applicationWithHistory.key}", it)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
@@ -66,6 +65,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildConfig
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
@@ -280,13 +280,13 @@ fun SettingsScreen(
|
||||
val historyDatabase = Amber.instance.getHistoryDatabase(it.npub)
|
||||
val deletedHistory = historyDatabase.dao().deleteOldHistory(oneWeekAgo)
|
||||
if (deletedHistory > 0) {
|
||||
Log.d(Amber.TAG, "Deleted $deletedHistory old history entries")
|
||||
AmberLog.d(Amber.TAG, "Deleted $deletedHistory old history entries")
|
||||
}
|
||||
|
||||
val logDatabase = Amber.instance.getLogDatabase(it.npub)
|
||||
val deletedLogs = logDatabase.dao().deleteOldLog(oneWeek)
|
||||
if (deletedLogs > 0) {
|
||||
Log.d(Amber.TAG, "Deleted $deletedLogs old log entries")
|
||||
AmberLog.d(Amber.TAG, "Deleted $deletedLogs old log entries")
|
||||
}
|
||||
|
||||
val dbFile = context.getDatabasePath("amber_db_${account.npub}")
|
||||
@@ -300,7 +300,7 @@ fun SettingsScreen(
|
||||
} catch (e: Exception) {
|
||||
isLoading = false
|
||||
if (e is CancellationException) throw e
|
||||
Log.e(Amber.TAG, "Error deleting old log entries", e)
|
||||
AmberLog.e(Amber.TAG, "Error deleting old log entries", e)
|
||||
val dbFile = context.getDatabasePath("amber_db_${account.npub}")
|
||||
val logFile = context.getDatabasePath("log_db_${account.npub}")
|
||||
val historyFile = context.getDatabasePath("history_db_${account.npub}")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.greenart7c3.nostrsigner.ui.actions
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -27,6 +26,7 @@ import androidx.paging.PagingConfig
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import androidx.paging.compose.itemKey
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.supportedKindNumbers
|
||||
import com.greenart7c3.nostrsigner.ui.ActivityFilter
|
||||
@@ -127,11 +127,11 @@ fun ActivityScreen(
|
||||
lazyPagingItems.apply {
|
||||
when (loadState.refresh) {
|
||||
is LoadState.Loading -> item {
|
||||
Log.d("ActivitiesScreen", "Loading...")
|
||||
AmberLog.d("ActivitiesScreen", "Loading...")
|
||||
Text("Loading...", Modifier.padding(16.dp))
|
||||
}
|
||||
is LoadState.Error -> item {
|
||||
Log.d("ActivitiesScreen", "Error loading data")
|
||||
AmberLog.d("ActivitiesScreen", "Error loading data")
|
||||
Text("Error loading data", Modifier.padding(16.dp))
|
||||
}
|
||||
is LoadState.NotLoading -> { }
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.greenart7c3.nostrsigner.ui.actions
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -55,6 +54,7 @@ import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
@@ -391,7 +391,7 @@ fun onAddRelay(
|
||||
}
|
||||
|
||||
override fun onDisconnected(relay: IRelayClient) {
|
||||
Log.d(Amber.TAG, "Disconnected from ${relay.url.url}")
|
||||
AmberLog.d(Amber.TAG, "Disconnected from ${relay.url.url}")
|
||||
super.onDisconnected(relay)
|
||||
}
|
||||
override fun onConnected(relay: IRelayClient, pingMillis: Int, compressed: Boolean) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.greenart7c3.nostrsigner.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -20,6 +19,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.AmberLog
|
||||
|
||||
val Shapes =
|
||||
Shapes(
|
||||
@@ -98,6 +98,6 @@ fun Color.light(factor: Float = 0.5f) = this.copy(alpha = this.alpha * factor)
|
||||
fun Color.Companion.fromHex(colorString: String) = try {
|
||||
Color("#$colorString".toColorInt())
|
||||
} catch (e: Exception) {
|
||||
Log.e(Amber.TAG, "Failed to parse color: $colorString", e)
|
||||
AmberLog.e(Amber.TAG, "Failed to parse color: $colorString", e)
|
||||
Unspecified
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user