From 75fe0559f2482378164a141b9e58b8a0bbac0813 Mon Sep 17 00:00:00 2001 From: Asim Ribo Date: Mon, 1 Jul 2024 20:29:26 +0200 Subject: [PATCH 01/21] Remove 2 provider setups and include the same setup in no-op manifest --- sentinel-no-op/src/main/AndroidManifest.xml | 5 +++++ sentinel/src/main/AndroidManifest.xml | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sentinel-no-op/src/main/AndroidManifest.xml b/sentinel-no-op/src/main/AndroidManifest.xml index ce089bd..287a45e 100644 --- a/sentinel-no-op/src/main/AndroidManifest.xml +++ b/sentinel-no-op/src/main/AndroidManifest.xml @@ -11,6 +11,11 @@ + + diff --git a/sentinel/src/main/AndroidManifest.xml b/sentinel/src/main/AndroidManifest.xml index 5d3da56..13a1b6f 100644 --- a/sentinel/src/main/AndroidManifest.xml +++ b/sentinel/src/main/AndroidManifest.xml @@ -112,13 +112,7 @@ - - Date: Fri, 5 Jul 2024 12:55:41 +0200 Subject: [PATCH 02/21] Revert "Remove 2 provider setups and include the same setup in no-op manifest" This reverts commit 75fe0559f2482378164a141b9e58b8a0bbac0813. --- sentinel-no-op/src/main/AndroidManifest.xml | 5 ----- sentinel/src/main/AndroidManifest.xml | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sentinel-no-op/src/main/AndroidManifest.xml b/sentinel-no-op/src/main/AndroidManifest.xml index 287a45e..ce089bd 100644 --- a/sentinel-no-op/src/main/AndroidManifest.xml +++ b/sentinel-no-op/src/main/AndroidManifest.xml @@ -11,11 +11,6 @@ - - diff --git a/sentinel/src/main/AndroidManifest.xml b/sentinel/src/main/AndroidManifest.xml index 13a1b6f..5d3da56 100644 --- a/sentinel/src/main/AndroidManifest.xml +++ b/sentinel/src/main/AndroidManifest.xml @@ -112,7 +112,13 @@ + + Date: Fri, 5 Jul 2024 14:10:27 +0200 Subject: [PATCH 03/21] Add check if WorkManager is initialized --- .../certificates/observer/SentinelWorkManager.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt index 944d7b3..8f2bef8 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt @@ -37,13 +37,15 @@ internal class SentinelWorkManager( } init { - WorkManager.initialize( - context, - Configuration.Builder() - .setMinimumLoggingLevel(android.util.Log.INFO) - .setWorkerFactory(workerFactory) - .build() - ) + if (WorkManager.isInitialized().not()) { + WorkManager.initialize( + context, + Configuration.Builder() + .setMinimumLoggingLevel(android.util.Log.INFO) + .setWorkerFactory(workerFactory) + .build() + ) + } } @RequiresApi(Build.VERSION_CODES.O) From d10925cb5e826228802636a13b344b5e50ff1308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 7 Jul 2024 15:43:24 +0200 Subject: [PATCH 04/21] Add delegate worker for certificate check To bypass restriction of now passing workerFactory to WorkManager configuration --- .../sentinel/di/component/DomainComponent.kt | 6 +- .../certificates/observer/DelegateWorker.kt | 69 +++++++++++++++++++ .../observer/SentinelWorkManager.kt | 29 ++++---- .../infinum/sentinel/ui/shared/Constants.kt | 2 + 4 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt index 2301cae..d51bef2 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt @@ -48,7 +48,9 @@ import com.infinum.sentinel.extensions.sizeTree import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorActivityCallbacks import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorNotificationCallbacks import com.infinum.sentinel.ui.bundles.details.BundleDetailsActivity +import com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker import com.infinum.sentinel.ui.certificates.observer.CertificatesObserver +import com.infinum.sentinel.ui.certificates.observer.DelegateWorker import com.infinum.sentinel.ui.certificates.observer.SentinelWorkManager import com.infinum.sentinel.ui.certificates.observer.SentinelWorkerFactory import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserver @@ -160,7 +162,9 @@ internal abstract class DomainComponent( @Provides @DomainScope fun sentinelWorkerFactory(): SentinelWorkerFactory = - SentinelWorkerFactory(collectors, notificationFactory) + SentinelWorkerFactory(collectors, notificationFactory).also { + DelegateWorker.workerFactories[CertificateCheckWorker.NAME] = it + } @Provides @DomainScope diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt new file mode 100644 index 0000000..7a78d21 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -0,0 +1,69 @@ +package com.infinum.sentinel.ui.certificates.observer + +import android.content.Context +import android.util.Log +import androidx.work.Data +import androidx.work.ListenableWorker +import androidx.work.WorkerFactory +import androidx.work.WorkerParameters +import com.google.common.util.concurrent.ListenableFuture +import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_CLASS_NAME +import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_ID +import java.util.concurrent.Executor +import java.util.concurrent.TimeUnit + +/** + * A worker to delegate work requests from within the library to workers + * that require factories with custom dependencies. + */ +internal class DelegateWorker( + appContext: Context, + parameters: WorkerParameters, +) : ListenableWorker(appContext, parameters) { + + private val workerClassName = + parameters.inputData.getString(WORKER_CLASS_NAME) ?: "" + private val workerId = parameters.inputData.getString(WORKER_ID) + private val delegateWorkerFactory = workerFactories[workerId] + private val delegateWorker = delegateWorkerFactory?.createWorker(appContext, workerClassName, parameters) + + override fun startWork(): ListenableFuture { + return if (delegateWorker != null) { + delegateWorker.startWork() + } else { + val errorMessage = "No delegateWorker available for $workerId" + + " with workerClassName of $workerClassName. Is the " + + "RouterWorker.workerFactories populated correctly?" + + Log.w("Sentinel", errorMessage) + + val errorData = Data.Builder().putString("Reason", errorMessage).build() + + object : ListenableFuture { + override fun isDone(): Boolean = true + override fun get(): Result = Result.failure(errorData) + override fun get(timeout: Long, unit: TimeUnit): Result = Result.failure(errorData) + override fun cancel(mayInterruptIfRunning: Boolean): Boolean = false + override fun isCancelled(): Boolean = false + override fun addListener(listener: Runnable, executor: Executor) = listener.run() + } + } + } + + companion object { + const val DELEGATE_WORKER_ID = "com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker" + + val workerFactories = object : AbstractMutableMap() { + + private val backingWorkerMap = mutableMapOf() + + // should be invoked only from the main thread + override fun put(key: String, value: WorkerFactory): WorkerFactory? { + return backingWorkerMap.put(key, value) + } + + override val entries: MutableSet> + get() = backingWorkerMap.entries + } + } +} \ No newline at end of file diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt index 8f2bef8..f847dc2 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt @@ -19,6 +19,8 @@ import com.infinum.sentinel.ui.shared.Constants.Keys.EXPIRE_IN_AMOUNT import com.infinum.sentinel.ui.shared.Constants.Keys.EXPIRE_IN_UNIT import com.infinum.sentinel.ui.shared.Constants.Keys.NOTIFY_INVALID_NOW import com.infinum.sentinel.ui.shared.Constants.Keys.NOTIFY_TO_EXPIRE +import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_CLASS_NAME +import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_ID import java.time.Duration import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @@ -49,25 +51,26 @@ internal class SentinelWorkManager( } @RequiresApi(Build.VERSION_CODES.O) - fun startCertificatesCheck(entity: CertificateMonitorEntity) = + fun startCertificatesCheck(entity: CertificateMonitorEntity) { + + val delegatedWorkData = workDataOf( + WORKER_CLASS_NAME to CertificateCheckWorker::class.qualifiedName, + WORKER_ID to CertificateCheckWorker.NAME, + NOTIFY_INVALID_NOW to entity.notifyInvalidNow, + NOTIFY_TO_EXPIRE to entity.notifyToExpire, + EXPIRE_IN_AMOUNT to entity.expireInAmount, + EXPIRE_IN_UNIT to entity.expireInUnit.name + ) WorkManager.getInstance(context) .enqueueUniquePeriodicWork( - CertificateCheckWorker.NAME, + DelegateWorker.DELEGATE_WORKER_ID, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, - PeriodicWorkRequestBuilder( + PeriodicWorkRequestBuilder( when (BuildConfig.DEBUG) { true -> Duration.ofMinutes(DEBUG_INTERVAL) false -> Duration.ofMinutes(RELEASE_INTERVAL) } - ) - .setInputData( - workDataOf( - NOTIFY_INVALID_NOW to entity.notifyInvalidNow, - NOTIFY_TO_EXPIRE to entity.notifyToExpire, - EXPIRE_IN_AMOUNT to entity.expireInAmount, - EXPIRE_IN_UNIT to entity.expireInUnit.name - ) - ) + ).setInputData(delegatedWorkData) .setConstraints( Constraints.Builder() .setRequiredNetworkType(NetworkType.NOT_REQUIRED) @@ -83,6 +86,8 @@ internal class SentinelWorkManager( .build() ) + } + fun certificatesCheckState(): Flow = WorkManager.getInstance(context) .getWorkInfosForUniqueWork(CertificateCheckWorker.NAME) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt index 3e4004f..5ae33f0 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt @@ -14,5 +14,7 @@ internal object Constants { const val NOTIFY_TO_EXPIRE: String = "KEY_NOTIFY_TO_EXPIRE" const val EXPIRE_IN_AMOUNT: String = "KEY_EXPIRE_IN_AMOUNT" const val EXPIRE_IN_UNIT: String = "KEY_EXPIRE_IN_UNIT" + const val WORKER_CLASS_NAME = "WORKER_CLASS_NAME" + const val WORKER_ID = "WORKER_ID" } } From b2bb4e75a313bbd5de8c30ba8e2035e766f4227a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 7 Jul 2024 15:49:03 +0200 Subject: [PATCH 05/21] Fix lint --- .../sentinel/ui/certificates/observer/DelegateWorker.kt | 8 ++++---- .../ui/certificates/observer/SentinelWorkManager.kt | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt index 7a78d21..6d06639 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -25,11 +25,11 @@ internal class DelegateWorker( parameters.inputData.getString(WORKER_CLASS_NAME) ?: "" private val workerId = parameters.inputData.getString(WORKER_ID) private val delegateWorkerFactory = workerFactories[workerId] - private val delegateWorker = delegateWorkerFactory?.createWorker(appContext, workerClassName, parameters) + private val delegatedWorker = delegateWorkerFactory?.createWorker(appContext, workerClassName, parameters) override fun startWork(): ListenableFuture { - return if (delegateWorker != null) { - delegateWorker.startWork() + return if (delegatedWorker != null) { + delegatedWorker.startWork() } else { val errorMessage = "No delegateWorker available for $workerId" + " with workerClassName of $workerClassName. Is the " + @@ -66,4 +66,4 @@ internal class DelegateWorker( get() = backingWorkerMap.entries } } -} \ No newline at end of file +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt index f847dc2..8b7af79 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt @@ -85,7 +85,6 @@ internal class SentinelWorkManager( ) .build() ) - } fun certificatesCheckState(): Flow = From 1eb3b48b518cc32f3f2a1a4f7f34e895aa7dd1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 7 Jul 2024 16:31:45 +0200 Subject: [PATCH 06/21] Add date format to exported logs And make them same as in logs list --- .../kotlin/com/infinum/sentinel/SentinelFileTree.kt | 7 +++++-- .../com/infinum/sentinel/ui/logger/LoggerAdapter.kt | 10 +++++++++- .../infinum/sentinel/ui/logger/LoggerViewHolder.kt | 8 ++++++-- .../infinum/sentinel/ui/logger/models/BaseEntry.kt | 8 ++++---- .../com/infinum/sentinel/ui/logs/LogsAdapter.kt | 13 ++++++++++--- .../com/infinum/sentinel/ui/logs/LogsViewHolder.kt | 9 ++------- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt index b09cb45..f507eb3 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt @@ -6,7 +6,8 @@ import com.infinum.sentinel.ui.logger.models.FlowBuffer import com.infinum.sentinel.ui.logger.models.Level import com.infinum.sentinel.ui.shared.LogFileResolver import java.io.File -import java.util.Calendar +import java.text.SimpleDateFormat +import java.util.Locale import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch @@ -21,6 +22,8 @@ internal class SentinelFileTree( private val logFileResolver = LogFileResolver(context) override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { + val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + MainScope().launch { withContext(Dispatchers.IO) { val entry = Entry( @@ -34,7 +37,7 @@ internal class SentinelFileTree( buffer.enqueue(entry) val file: File = logFileResolver.createOrOpenFile() - val line = entry.asLineString() + val line = entry.asLineString(dateTimeFormat) file.appendText(line) } diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt index 46d750f..2ca2cd7 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt @@ -5,12 +5,16 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import com.infinum.sentinel.SentinelFileTree import com.infinum.sentinel.databinding.SentinelItemLogBinding +import java.text.SimpleDateFormat +import java.util.Locale internal class LoggerAdapter( private val onListChanged: (Boolean) -> Unit, private val onClick: (SentinelFileTree.Entry) -> Unit ) : ListAdapter(LoggerDiffUtil()) { + private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LoggerViewHolder = LoggerViewHolder( SentinelItemLogBinding.inflate( @@ -21,7 +25,11 @@ internal class LoggerAdapter( ) override fun onBindViewHolder(holder: LoggerViewHolder, position: Int) { - holder.bind(getItem(position), onClick) + holder.bind( + item = getItem(position), + dateTimeFormat = dateTimeFormat, + onClick = onClick + ) } override fun onViewRecycled(holder: LoggerViewHolder) { diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerViewHolder.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerViewHolder.kt index 5be2992..ce2361e 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerViewHolder.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerViewHolder.kt @@ -14,7 +14,11 @@ internal class LoggerViewHolder( private val binding: SentinelItemLogBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: SentinelFileTree.Entry?, onClick: (SentinelFileTree.Entry) -> Unit) { + fun bind( + item: SentinelFileTree.Entry?, + dateTimeFormat: SimpleDateFormat, + onClick: (SentinelFileTree.Entry) -> Unit + ) { item?.let { entry -> with(binding) { levelView.setBackgroundColor( @@ -31,7 +35,7 @@ internal class LoggerViewHolder( } ) ) - timestampView.text = SimpleDateFormat.getDateTimeInstance().format(Date(entry.timestamp)) + timestampView.text = dateTimeFormat.format(Date(entry.timestamp)) tagView.text = entry.tag entry.stackTrace?.let { stackTraceView.text = it diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/BaseEntry.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/BaseEntry.kt index 7ec2e2b..9feadbf 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/BaseEntry.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/BaseEntry.kt @@ -1,6 +1,7 @@ package com.infinum.sentinel.ui.logger.models -import java.io.File +import java.text.SimpleDateFormat +import java.util.Date import org.json.JSONObject internal open class BaseEntry( @@ -10,7 +11,6 @@ internal open class BaseEntry( open val message: String? = null, open val stackTrace: String? = null ) { - fun asJSONString(): String = JSONObject() .put("level", level) @@ -20,9 +20,9 @@ internal open class BaseEntry( .put("stackTrace", stackTrace) .toString() - fun asLineString(): String = + fun asLineString(dateTimeFormat: SimpleDateFormat): String = buildString { - append(timestamp) + append(dateTimeFormat.format(Date(timestamp))) append(" LEVEL: ") append(level) append(" TAG: ") diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt index 8913309..d2c0324 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt @@ -3,10 +3,10 @@ package com.infinum.sentinel.ui.logs import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter -import com.infinum.sentinel.SentinelFileTree -import com.infinum.sentinel.databinding.SentinelItemLogBinding import com.infinum.sentinel.databinding.SentinelItemLogFileBinding import java.io.File +import java.text.SimpleDateFormat +import java.util.Locale internal class LogsAdapter( private val onListChanged: (Boolean) -> Unit, @@ -14,6 +14,8 @@ internal class LogsAdapter( private val onShare: (File) -> Unit ) : ListAdapter(LogsDiffUtil()) { + private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LogsViewHolder = LogsViewHolder( SentinelItemLogFileBinding.inflate( @@ -24,7 +26,12 @@ internal class LogsAdapter( ) override fun onBindViewHolder(holder: LogsViewHolder, position: Int) { - holder.bind(getItem(position), onDelete, onShare) + holder.bind( + item = getItem(position), + dateTimeFormat = dateTimeFormat, + onDelete = onDelete, + onShare = onShare + ) } override fun onViewRecycled(holder: LogsViewHolder) { diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsViewHolder.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsViewHolder.kt index 61c2d60..da7df10 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsViewHolder.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsViewHolder.kt @@ -1,12 +1,7 @@ package com.infinum.sentinel.ui.logs -import androidx.core.content.ContextCompat -import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import com.infinum.sentinel.R -import com.infinum.sentinel.SentinelFileTree import com.infinum.sentinel.databinding.SentinelItemLogFileBinding -import com.infinum.sentinel.ui.logger.models.Level import java.io.File import java.text.SimpleDateFormat import java.util.Date @@ -15,11 +10,11 @@ internal class LogsViewHolder( private val binding: SentinelItemLogFileBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: File?, onDelete: (File) -> Unit, onShare: (File) -> Unit) { + fun bind(item: File?, dateTimeFormat: SimpleDateFormat, onDelete: (File) -> Unit, onShare: (File) -> Unit) { item?.let { entry -> with(binding) { messageView.text = entry.name - timestampView.text = SimpleDateFormat.getDateTimeInstance().format(Date(entry.lastModified())) + timestampView.text = dateTimeFormat.format(Date(entry.lastModified())) deleteButton.setOnClickListener { onDelete(entry) } shareButton.setOnClickListener { onShare(entry) } } From c2a8f284a2760e0c4d98b7a03263e2c2ec978864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 7 Jul 2024 19:15:28 +0200 Subject: [PATCH 07/21] Add sort to shared prefs tool --- .../data/models/raw/PreferencesData.kt | 3 +- .../main/preferences/PreferencesFragment.kt | 3 ++ .../main/preferences/PreferencesViewModel.kt | 21 ++++++++++++++ .../main/res/drawable/sentinel_ic_sort.xml | 11 ++++++++ .../layout/sentinel_view_item_preference.xml | 28 +++++++++++++++---- sentinel/src/main/res/values/strings.xml | 1 + 6 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 sentinel/src/main/res/drawable/sentinel_ic_sort.xml diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt index 627390d..603448e 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt @@ -2,5 +2,6 @@ package com.infinum.sentinel.data.models.raw internal data class PreferencesData( val name: String, - val values: List> + val values: List>, + val isSortedAscending: Boolean = false, ) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt index 8ec5464..7a70cba 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt @@ -69,6 +69,9 @@ internal class PreferencesFragment : SentinelViewItemPreferenceBinding.inflate(layoutInflater, binding.contentLayout, false) .apply { nameView.text = data.name + sortImageView.setOnClickListener { + viewModel.onSortClicked(data) + } data.values.forEach { tuple -> prefsLayout.addView( SentinelViewItemTextBinding.inflate(layoutInflater, prefsLayout, false) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt index 0299b8c..4c4b1f4 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt @@ -1,6 +1,7 @@ package com.infinum.sentinel.ui.main.preferences import com.infinum.sentinel.data.models.raw.PreferenceType +import com.infinum.sentinel.data.models.raw.PreferencesData import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.preference.models.PreferenceParameters @@ -38,4 +39,24 @@ internal class PreferencesViewModel( } emitEvent(PreferencesEvent.Cached()) } + + fun onSortClicked(data: PreferencesData) { + val currentValues = (stateFlow.value as? PreferencesState.Data)?.value.orEmpty() + val sortedData = if (data.isSortedAscending) { + data.values.sortedByDescending { it.second } + } else { + data.values.sortedBy { it.second } + } + val changedValues = currentValues.map { preferencesData -> + if (preferencesData.name == data.name) { + preferencesData.copy( + values = sortedData, + isSortedAscending = !preferencesData.isSortedAscending + ) + } else { + preferencesData + } + } + setState(PreferencesState.Data(value = changedValues)) + } } diff --git a/sentinel/src/main/res/drawable/sentinel_ic_sort.xml b/sentinel/src/main/res/drawable/sentinel_ic_sort.xml new file mode 100644 index 0000000..7e84ccd --- /dev/null +++ b/sentinel/src/main/res/drawable/sentinel_ic_sort.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml index b894bb5..9fe5e8d 100644 --- a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml +++ b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml @@ -1,18 +1,36 @@ - + android:orientation="horizontal"> + + + + + + Fragment arguments Fragment Saved State + Sort preferences by name Preferences editor Key Current value From f95f4db2a120d826be938494bff97d164a43183c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Mon, 8 Jul 2024 07:43:33 +0200 Subject: [PATCH 08/21] Extract log date time format --- .../com/infinum/sentinel/SentinelFileTree.kt | 3 +- .../com/infinum/sentinel/TimberInitializer.kt | 1 - .../sentinel/ui/logger/LoggerActivity.kt | 31 +++++++++---------- .../sentinel/ui/logger/LoggerAdapter.kt | 3 +- .../sentinel/ui/logger/models/FlowBuffer.kt | 4 +-- .../infinum/sentinel/ui/logs/LogsActivity.kt | 31 +++++++++---------- .../infinum/sentinel/ui/logs/LogsAdapter.kt | 3 +- .../infinum/sentinel/ui/shared/Constants.kt | 5 +++ 8 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt index f507eb3..81a6b52 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt @@ -4,6 +4,7 @@ import android.content.Context import com.infinum.sentinel.ui.logger.models.BaseEntry import com.infinum.sentinel.ui.logger.models.FlowBuffer import com.infinum.sentinel.ui.logger.models.Level +import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT import com.infinum.sentinel.ui.shared.LogFileResolver import java.io.File import java.text.SimpleDateFormat @@ -22,7 +23,7 @@ internal class SentinelFileTree( private val logFileResolver = LogFileResolver(context) override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { - val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + val dateTimeFormat = SimpleDateFormat(LOG_DATE_TIME_FORMAT, Locale.getDefault()) MainScope().launch { withContext(Dispatchers.IO) { diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/TimberInitializer.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/TimberInitializer.kt index 8125b82..804a728 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/TimberInitializer.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/TimberInitializer.kt @@ -3,7 +3,6 @@ package com.infinum.sentinel import android.content.Context import androidx.startup.Initializer import com.infinum.sentinel.ui.logger.models.FlowBuffer -import kotlinx.coroutines.MainScope import timber.log.Timber public class TimberInitializer : Initializer> { diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerActivity.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerActivity.kt index fc6a2c9..c0235f9 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerActivity.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerActivity.kt @@ -36,7 +36,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber - public class LoggerActivity : AppCompatActivity() { private companion object { @@ -94,21 +93,21 @@ public class LoggerActivity : AppCompatActivity() { with(binding) { toolbar.setNavigationOnClickListener { finish() } toolbar.subtitle = ( - packageManager.getApplicationLabel( - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - packageManager.getApplicationInfo( - packageName, - PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()) - ) - } else { - @Suppress("DEPRECATION") - packageManager.getApplicationInfo( - packageName, - PackageManager.GET_META_DATA - ) - } - ) as? String - ) ?: getString(R.string.sentinel_name) + packageManager.getApplicationLabel( + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager.getApplicationInfo( + packageName, + PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()) + ) + } else { + @Suppress("DEPRECATION") + packageManager.getApplicationInfo( + packageName, + PackageManager.GET_META_DATA + ) + } + ) as? String + ) ?: getString(R.string.sentinel_name) toolbar.setOnMenuItemClickListener { when (it.itemId) { R.id.search -> { diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt index 2ca2cd7..7393cc2 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import com.infinum.sentinel.SentinelFileTree import com.infinum.sentinel.databinding.SentinelItemLogBinding +import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT import java.text.SimpleDateFormat import java.util.Locale @@ -13,7 +14,7 @@ internal class LoggerAdapter( private val onClick: (SentinelFileTree.Entry) -> Unit ) : ListAdapter(LoggerDiffUtil()) { - private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + private val dateTimeFormat = SimpleDateFormat(LOG_DATE_TIME_FORMAT, Locale.getDefault()) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LoggerViewHolder = LoggerViewHolder( diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/FlowBuffer.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/FlowBuffer.kt index d51ee6d..19c1af5 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/FlowBuffer.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/models/FlowBuffer.kt @@ -28,8 +28,8 @@ internal class FlowBuffer { } else { queue.reversed().filter { it.tag?.lowercase()?.contains(query.lowercase()) == true || - it.message?.lowercase()?.contains(query.lowercase()) == true || - it.stackTrace?.lowercase()?.contains(query.lowercase()) == true + it.message?.lowercase()?.contains(query.lowercase()) == true || + it.stackTrace?.lowercase()?.contains(query.lowercase()) == true } } ) diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsActivity.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsActivity.kt index 65a0da0..8f3e1e6 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsActivity.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsActivity.kt @@ -29,7 +29,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext - public class LogsActivity : AppCompatActivity() { private companion object { @@ -79,21 +78,21 @@ public class LogsActivity : AppCompatActivity() { with(binding) { toolbar.setNavigationOnClickListener { finish() } toolbar.subtitle = ( - packageManager.getApplicationLabel( - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - packageManager.getApplicationInfo( - packageName, - PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()) - ) - } else { - @Suppress("DEPRECATION") - packageManager.getApplicationInfo( - packageName, - PackageManager.GET_META_DATA - ) - } - ) as? String - ) ?: getString(R.string.sentinel_name) + packageManager.getApplicationLabel( + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager.getApplicationInfo( + packageName, + PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()) + ) + } else { + @Suppress("DEPRECATION") + packageManager.getApplicationInfo( + packageName, + PackageManager.GET_META_DATA + ) + } + ) as? String + ) ?: getString(R.string.sentinel_name) recyclerView.layoutManager = LinearLayoutManager( recyclerView.context, diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt index d2c0324..589e520 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import com.infinum.sentinel.databinding.SentinelItemLogFileBinding +import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT import java.io.File import java.text.SimpleDateFormat import java.util.Locale @@ -14,7 +15,7 @@ internal class LogsAdapter( private val onShare: (File) -> Unit ) : ListAdapter(LogsDiffUtil()) { - private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss. SSSZ", Locale.getDefault()) + private val dateTimeFormat = SimpleDateFormat(LOG_DATE_TIME_FORMAT, Locale.getDefault()) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LogsViewHolder = LogsViewHolder( diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt new file mode 100644 index 0000000..68127b6 --- /dev/null +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt @@ -0,0 +1,5 @@ +package com.infinum.sentinel.ui.shared + +internal object Constants { + const val LOG_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" +} From 01ea4b1770f42382bbfbb1c8345102889bb81cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Tue, 9 Jul 2024 17:34:09 +0200 Subject: [PATCH 09/21] Add sort to list of shared prefs files --- .../data/sources/raw/collectors/PreferencesCollector.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PreferencesCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PreferencesCollector.kt index 882f71c..b9660d7 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PreferencesCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PreferencesCollector.kt @@ -29,6 +29,8 @@ internal class PreferencesCollector( prefsDirectory.list().orEmpty().toList().map { it.removeSuffix(PREFS_SUFFIX) } } else { listOf() + }.sortedBy { name -> + name }.map { name -> val allPrefs = getSharedPreferences(name, MODE_PRIVATE).all val tuples = allPrefs.keys.toSet().mapNotNull { From 819fc777e446b8cd02ec33816aafabd706cf709f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Tue, 9 Jul 2024 17:52:05 +0200 Subject: [PATCH 10/21] Add option to expand/hide certain shared prefs file --- .../data/models/raw/PreferencesData.kt | 1 + .../main/preferences/PreferencesFragment.kt | 58 ++++++++++++------- .../main/preferences/PreferencesViewModel.kt | 16 +++++ .../layout/sentinel_view_item_preference.xml | 14 ++++- sentinel/src/main/res/values/strings.xml | 1 + 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt index 603448e..16ac160 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/raw/PreferencesData.kt @@ -4,4 +4,5 @@ internal data class PreferencesData( val name: String, val values: List>, val isSortedAscending: Boolean = false, + val isExpanded: Boolean = true, ) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt index 7a70cba..86f8c7f 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt @@ -64,7 +64,6 @@ internal class PreferencesFragment : } } - @Suppress("UNCHECKED_CAST") private fun createItemView(data: PreferencesData): View = SentinelViewItemPreferenceBinding.inflate(layoutInflater, binding.contentLayout, false) .apply { @@ -72,27 +71,42 @@ internal class PreferencesFragment : sortImageView.setOnClickListener { viewModel.onSortClicked(data) } - data.values.forEach { tuple -> - prefsLayout.addView( - SentinelViewItemTextBinding.inflate(layoutInflater, prefsLayout, false) - .apply { - labelView.isAllCaps = false - labelView.text = tuple.second - valueView.text = tuple.third.toString() - root.setOnClickListener { _ -> - viewModel.cache( - data.name, - tuple - ) - } - root.setOnLongClickListener { - it.context.copyToClipboard( - key = tuple.second, - value = tuple.third.toString() - ) - } - }.root - ) + hideExpandImageView.setOnClickListener { + viewModel.onHideExpandClicked(data) + } + + if (data.isExpanded) { + prefsLayout.visibility = View.VISIBLE + hideExpandImageView.setImageResource(R.drawable.sentinel_ic_minus) + showPreferenceData(data) + } else { + prefsLayout.visibility = View.GONE + hideExpandImageView.setImageResource(R.drawable.sentinel_ic_plus) } }.root + + private fun SentinelViewItemPreferenceBinding.showPreferenceData(data: PreferencesData) { + data.values.forEach { tuple -> + prefsLayout.addView( + SentinelViewItemTextBinding.inflate(layoutInflater, prefsLayout, false) + .apply { + labelView.isAllCaps = false + labelView.text = tuple.second + valueView.text = tuple.third.toString() + root.setOnClickListener { _ -> + viewModel.cache( + data.name, + tuple + ) + } + root.setOnLongClickListener { + it.context.copyToClipboard( + key = tuple.second, + value = tuple.third.toString() + ) + } + }.root + ) + } + } } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt index 4c4b1f4..b81e27e 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesViewModel.kt @@ -59,4 +59,20 @@ internal class PreferencesViewModel( } setState(PreferencesState.Data(value = changedValues)) } + + fun onHideExpandClicked(data: PreferencesData) { + (stateFlow.value as? PreferencesState.Data)?.let { state -> + val currentValues = state.value + val changedValues = currentValues.map { preferencesData -> + if (preferencesData.name == data.name) { + preferencesData.copy( + isExpanded = !preferencesData.isExpanded + ) + } else { + preferencesData + } + } + setState(PreferencesState.Data(value = changedValues)) + } + } } diff --git a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml index 9fe5e8d..660ee02 100644 --- a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml +++ b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml @@ -10,7 +10,8 @@ + android:orientation="horizontal" + android:paddingBottom="8dp"> + + + Fragment Saved State Sort preferences by name + Hide/expands the preferences Preferences editor Key Current value From e703f4124aef7abe4cd522aa324e594a540104ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Tue, 9 Jul 2024 18:14:56 +0200 Subject: [PATCH 11/21] Improve shared prefs option UX --- .../ui/main/preferences/PreferencesFragment.kt | 2 ++ .../res/layout/sentinel_view_item_preference.xml | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt index 86f8c7f..d4f241c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt @@ -77,10 +77,12 @@ internal class PreferencesFragment : if (data.isExpanded) { prefsLayout.visibility = View.VISIBLE + sortImageView.visibility = View.VISIBLE hideExpandImageView.setImageResource(R.drawable.sentinel_ic_minus) showPreferenceData(data) } else { prefsLayout.visibility = View.GONE + sortImageView.visibility = View.GONE hideExpandImageView.setImageResource(R.drawable.sentinel_ic_plus) } }.root diff --git a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml index 660ee02..d1bbd0d 100644 --- a/sentinel/src/main/res/layout/sentinel_view_item_preference.xml +++ b/sentinel/src/main/res/layout/sentinel_view_item_preference.xml @@ -24,24 +24,25 @@ tools:text="Preferences" /> + android:contentDescription="@string/sentinel_sort_preference_by_name" + android:src="@drawable/sentinel_ic_sort" /> + android:contentDescription="@string/sentinel_hide_expands_the_preferences" + android:src="@drawable/sentinel_ic_plus" /> + Date: Wed, 10 Jul 2024 07:58:16 +0200 Subject: [PATCH 12/21] Improve readability of code --- .../ui/main/preferences/PreferencesFragment.kt | 14 +++++++------- sentinel/src/main/res/values/strings.xml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt index d4f241c..d1337e5 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/PreferencesFragment.kt @@ -88,23 +88,23 @@ internal class PreferencesFragment : }.root private fun SentinelViewItemPreferenceBinding.showPreferenceData(data: PreferencesData) { - data.values.forEach { tuple -> + data.values.forEach { (preferenceType, label, value) -> prefsLayout.addView( SentinelViewItemTextBinding.inflate(layoutInflater, prefsLayout, false) .apply { labelView.isAllCaps = false - labelView.text = tuple.second - valueView.text = tuple.third.toString() + labelView.text = label + valueView.text = value.toString() root.setOnClickListener { _ -> viewModel.cache( - data.name, - tuple + name = data.name, + tuple = Triple(preferenceType, label, value) ) } root.setOnLongClickListener { it.context.copyToClipboard( - key = tuple.second, - value = tuple.third.toString() + key = label, + value = value.toString() ) } }.root diff --git a/sentinel/src/main/res/values/strings.xml b/sentinel/src/main/res/values/strings.xml index be00e80..6754d59 100644 --- a/sentinel/src/main/res/values/strings.xml +++ b/sentinel/src/main/res/values/strings.xml @@ -85,7 +85,7 @@ Fragment Saved State Sort preferences by name - Hide/expands the preferences + Hide/expand the preferences Preferences editor Key Current value From e80a050f6037fcd28ba0630acac36454ce045e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 14 Jul 2024 15:40:52 +0200 Subject: [PATCH 13/21] Add annotation to UI thread only method --- .../sentinel/ui/certificates/observer/DelegateWorker.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt index 6d06639..aea177b 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -2,6 +2,7 @@ package com.infinum.sentinel.ui.certificates.observer import android.content.Context import android.util.Log +import androidx.annotation.UiThread import androidx.work.Data import androidx.work.ListenableWorker import androidx.work.WorkerFactory @@ -57,7 +58,7 @@ internal class DelegateWorker( private val backingWorkerMap = mutableMapOf() - // should be invoked only from the main thread + @UiThread override fun put(key: String, value: WorkerFactory): WorkerFactory? { return backingWorkerMap.put(key, value) } From f7666a1fa97998a696ff363c2f1f85df14cf99f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 14 Jul 2024 15:48:08 +0200 Subject: [PATCH 14/21] Remove redundant manifest tags --- sentinel/src/main/AndroidManifest.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sentinel/src/main/AndroidManifest.xml b/sentinel/src/main/AndroidManifest.xml index 5d3da56..13a1b6f 100644 --- a/sentinel/src/main/AndroidManifest.xml +++ b/sentinel/src/main/AndroidManifest.xml @@ -112,13 +112,7 @@ - - Date: Sun, 14 Jul 2024 16:07:09 +0200 Subject: [PATCH 15/21] Update manifest with permission to use sentinel --- sentinel/src/main/AndroidManifest.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sentinel/src/main/AndroidManifest.xml b/sentinel/src/main/AndroidManifest.xml index 5d3da56..394f16e 100644 --- a/sentinel/src/main/AndroidManifest.xml +++ b/sentinel/src/main/AndroidManifest.xml @@ -3,6 +3,10 @@ + + - + From 7f79a81e88c9bf15a53e7f37c69d6a4c2e00734f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Sun, 14 Jul 2024 16:07:27 +0200 Subject: [PATCH 16/21] Reneme timber tool constants object --- .../src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt | 2 +- .../main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt | 2 +- .../src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt | 2 +- .../sentinel/ui/shared/{Constants.kt => TimberToolConstants.kt} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/{Constants.kt => TimberToolConstants.kt} (73%) diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt index 81a6b52..3fdbde5 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/SentinelFileTree.kt @@ -4,7 +4,7 @@ import android.content.Context import com.infinum.sentinel.ui.logger.models.BaseEntry import com.infinum.sentinel.ui.logger.models.FlowBuffer import com.infinum.sentinel.ui.logger.models.Level -import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT +import com.infinum.sentinel.ui.shared.TimberToolConstants.LOG_DATE_TIME_FORMAT import com.infinum.sentinel.ui.shared.LogFileResolver import java.io.File import java.text.SimpleDateFormat diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt index 7393cc2..05c0004 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logger/LoggerAdapter.kt @@ -5,7 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import com.infinum.sentinel.SentinelFileTree import com.infinum.sentinel.databinding.SentinelItemLogBinding -import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT +import com.infinum.sentinel.ui.shared.TimberToolConstants.LOG_DATE_TIME_FORMAT import java.text.SimpleDateFormat import java.util.Locale diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt index 589e520..55abf53 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/logs/LogsAdapter.kt @@ -4,7 +4,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import com.infinum.sentinel.databinding.SentinelItemLogFileBinding -import com.infinum.sentinel.ui.shared.Constants.LOG_DATE_TIME_FORMAT +import com.infinum.sentinel.ui.shared.TimberToolConstants.LOG_DATE_TIME_FORMAT import java.io.File import java.text.SimpleDateFormat import java.util.Locale diff --git a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/TimberToolConstants.kt similarity index 73% rename from tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt rename to tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/TimberToolConstants.kt index 68127b6..1ae9d57 100644 --- a/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt +++ b/tool-timber/src/main/kotlin/com/infinum/sentinel/ui/shared/TimberToolConstants.kt @@ -1,5 +1,5 @@ package com.infinum.sentinel.ui.shared -internal object Constants { +internal object TimberToolConstants { const val LOG_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" } From 8e5998df6032c475fed4d00167023e061f7adf0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Wed, 17 Jul 2024 16:56:11 +0200 Subject: [PATCH 17/21] Remove unnecessary work manager initialization --- sentinel/src/main/AndroidManifest.xml | 11 +++-------- .../ui/certificates/observer/SentinelWorkManager.kt | 13 ------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/sentinel/src/main/AndroidManifest.xml b/sentinel/src/main/AndroidManifest.xml index bdf9379..61a5144 100644 --- a/sentinel/src/main/AndroidManifest.xml +++ b/sentinel/src/main/AndroidManifest.xml @@ -13,10 +13,10 @@ android:name=".ui.main.SentinelActivity" android:exported="true" android:label="@string/sentinel_name" + android:permission="com.infinum.sentinel.permission.ACCESS_SENTINEL" android:taskAffinity="com.infinum.sentinel" - android:theme="@style/Sentinel.Theme" - android:permission="com.infinum.sentinel.permission.ACCESS_SENTINEL"> - + @@ -117,11 +117,6 @@ - - diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt index 8b7af79..1059309 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt @@ -4,7 +4,6 @@ import android.content.Context import android.os.Build import androidx.annotation.RequiresApi import androidx.lifecycle.asFlow -import androidx.work.Configuration import androidx.work.Constraints import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.NetworkType @@ -38,18 +37,6 @@ internal class SentinelWorkManager( private const val RELEASE_INTERVAL = 1440L } - init { - if (WorkManager.isInitialized().not()) { - WorkManager.initialize( - context, - Configuration.Builder() - .setMinimumLoggingLevel(android.util.Log.INFO) - .setWorkerFactory(workerFactory) - .build() - ) - } - } - @RequiresApi(Build.VERSION_CODES.O) fun startCertificatesCheck(entity: CertificateMonitorEntity) { From 337d91f8c12870ce2e4a1a13346b9d573cfbc800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Wed, 17 Jul 2024 17:01:00 +0200 Subject: [PATCH 18/21] Typo fix --- .../infinum/sentinel/ui/certificates/observer/DelegateWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt index aea177b..a063255 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -34,7 +34,7 @@ internal class DelegateWorker( } else { val errorMessage = "No delegateWorker available for $workerId" + " with workerClassName of $workerClassName. Is the " + - "RouterWorker.workerFactories populated correctly?" + "DelegateWorker.workerFactories populated correctly?" Log.w("Sentinel", errorMessage) From fbdf3a92cd144073d19035f01b8d5704cd44e9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Wed, 17 Jul 2024 17:04:37 +0200 Subject: [PATCH 19/21] Replace failure result with exception --- .../ui/certificates/observer/DelegateWorker.kt | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt index a063255..b4b503b 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -35,19 +35,7 @@ internal class DelegateWorker( val errorMessage = "No delegateWorker available for $workerId" + " with workerClassName of $workerClassName. Is the " + "DelegateWorker.workerFactories populated correctly?" - - Log.w("Sentinel", errorMessage) - - val errorData = Data.Builder().putString("Reason", errorMessage).build() - - object : ListenableFuture { - override fun isDone(): Boolean = true - override fun get(): Result = Result.failure(errorData) - override fun get(timeout: Long, unit: TimeUnit): Result = Result.failure(errorData) - override fun cancel(mayInterruptIfRunning: Boolean): Boolean = false - override fun isCancelled(): Boolean = false - override fun addListener(listener: Runnable, executor: Executor) = listener.run() - } + throw IllegalStateException(errorMessage) } } From bbd0d8a2a0eb7c1e392d08055dde0227f719b60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Wed, 17 Jul 2024 17:42:01 +0200 Subject: [PATCH 20/21] Improve DI setup for work manager --- .../com/infinum/sentinel/di/LibraryComponents.kt | 1 + .../infinum/sentinel/di/WorkManagerInitializer.kt | 14 ++++++++++++++ .../sentinel/di/component/DomainComponent.kt | 14 +------------- .../ui/certificates/observer/DelegateWorker.kt | 4 ---- .../certificates/observer/SentinelWorkManager.kt | 2 -- 5 files changed, 16 insertions(+), 19 deletions(-) create mode 100644 sentinel/src/main/kotlin/com/infinum/sentinel/di/WorkManagerInitializer.kt diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt index 72d71cb..68800d7 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt @@ -42,6 +42,7 @@ internal object LibraryComponents { tools.filterIsInstance().firstOrNull()?.userCertificates.orEmpty(), onTriggered ) + WorkManagerInitializer.init(domainComponent) domainComponent.setup() } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/WorkManagerInitializer.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/WorkManagerInitializer.kt new file mode 100644 index 0000000..49f278c --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/WorkManagerInitializer.kt @@ -0,0 +1,14 @@ +package com.infinum.sentinel.di + +import com.infinum.sentinel.di.component.DomainComponent +import com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker +import com.infinum.sentinel.ui.certificates.observer.DelegateWorker +import com.infinum.sentinel.ui.certificates.observer.SentinelWorkerFactory + +internal object WorkManagerInitializer { + + fun init(domainComponent: DomainComponent) { + DelegateWorker.workerFactories[CertificateCheckWorker.NAME] = + SentinelWorkerFactory(domainComponent.collectors, domainComponent.notificationFactory) + } +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt index d51bef2..f994549 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt @@ -48,11 +48,8 @@ import com.infinum.sentinel.extensions.sizeTree import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorActivityCallbacks import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorNotificationCallbacks import com.infinum.sentinel.ui.bundles.details.BundleDetailsActivity -import com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker import com.infinum.sentinel.ui.certificates.observer.CertificatesObserver -import com.infinum.sentinel.ui.certificates.observer.DelegateWorker import com.infinum.sentinel.ui.certificates.observer.SentinelWorkManager -import com.infinum.sentinel.ui.certificates.observer.SentinelWorkerFactory import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserver import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserverRunnable import com.infinum.sentinel.ui.crash.anr.SentinelUiAnrObserver @@ -93,8 +90,6 @@ internal abstract class DomainComponent( abstract val sentinelAnrObserver: SentinelAnrObserver - abstract val sentinelWorkerFactory: SentinelWorkerFactory - abstract val sentinelWorkManager: SentinelWorkManager abstract val sentinelAnrObserverRunnable: SentinelAnrObserverRunnable @@ -159,17 +154,10 @@ internal abstract class DomainComponent( fun sentinelAnrObserverRunnable(dao: CrashesDao): SentinelAnrObserverRunnable = SentinelAnrObserverRunnable(context, notificationFactory, dao) - @Provides - @DomainScope - fun sentinelWorkerFactory(): SentinelWorkerFactory = - SentinelWorkerFactory(collectors, notificationFactory).also { - DelegateWorker.workerFactories[CertificateCheckWorker.NAME] = it - } - @Provides @DomainScope fun sentinelWorkManager(): SentinelWorkManager = - SentinelWorkManager(context, sentinelWorkerFactory) + SentinelWorkManager(context) @Provides @DomainScope diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt index b4b503b..318599d 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/DelegateWorker.kt @@ -1,17 +1,13 @@ package com.infinum.sentinel.ui.certificates.observer import android.content.Context -import android.util.Log import androidx.annotation.UiThread -import androidx.work.Data import androidx.work.ListenableWorker import androidx.work.WorkerFactory import androidx.work.WorkerParameters import com.google.common.util.concurrent.ListenableFuture import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_CLASS_NAME import com.infinum.sentinel.ui.shared.Constants.Keys.WORKER_ID -import java.util.concurrent.Executor -import java.util.concurrent.TimeUnit /** * A worker to delegate work requests from within the library to workers diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt index 1059309..6d3103e 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkManager.kt @@ -10,7 +10,6 @@ import androidx.work.NetworkType import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkInfo import androidx.work.WorkManager -import androidx.work.WorkerFactory import androidx.work.workDataOf import com.infinum.sentinel.BuildConfig import com.infinum.sentinel.data.models.local.CertificateMonitorEntity @@ -29,7 +28,6 @@ import me.tatarka.inject.annotations.Inject @Inject internal class SentinelWorkManager( private val context: Context, - private val workerFactory: WorkerFactory ) { companion object { From 1d22f194a1adc836f9b71010ae6e78d9afd0fef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C4=8Ceh?= Date: Thu, 18 Jul 2024 12:22:17 +0200 Subject: [PATCH 21/21] Bump version to 1.4.0 --- README.md | 6 +++--- config.gradle | 4 ++-- gradle/libs.versions.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0b2dbff..d0328ee 100644 --- a/README.md +++ b/README.md @@ -57,15 +57,15 @@ Then add the following dependencies in your app `build.gradle` or `build.gradle. **Groovy** ```groovy -def sentinelVersion = "1.3.3" +def sentinelVersion = "1.4.0" debugImplementation "com.infinum.sentinel:sentinel:$sentinelVersion" -releaseImplementation "com.infinum.sentinel:sentinel-noop:$sentinelVersion" +releaseImplementation "com.infinum.sentinel:sentinel-no-op:$sentinelVersion" ``` **KotlinDSL** ```kotlin -val sentinelVersion = "1.3.3" +val sentinelVersion = "1.4.0" debugImplementation("com.infinum.sentinel:sentinel:$sentinelVersion") releaseImplementation("com.infinum.sentinel:sentinel-no-op:$sentinelVersion") ``` diff --git a/config.gradle b/config.gradle index f1557fe..dfb8f51 100644 --- a/config.gradle +++ b/config.gradle @@ -1,7 +1,7 @@ ext { def major = 1 - def minor = 3 - def patch = 3 + def minor = 4 + def patch = 0 buildConfig = [ "minSdk" : 21, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1dadde7..0ab73b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -sentinel = "1.3.3" +sentinel = "1.4.0" gradle = "8.3.2" kotlin = "1.9.22" coroutines = "1.8.0"