Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Master with Release 1.4.0 #75

Merged
merged 29 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
75fe055
Remove 2 provider setups and include the same setup in no-op manifest
AsimRibo Jul 1, 2024
8c0568a
Revert "Remove 2 provider setups and include the same setup in no-op …
KCeh Jul 5, 2024
4b64129
Add check if WorkManager is initialized
KCeh Jul 5, 2024
d10925c
Add delegate worker for certificate check
KCeh Jul 7, 2024
b2bb4e7
Fix lint
KCeh Jul 7, 2024
1eb3b48
Add date format to exported logs
KCeh Jul 7, 2024
c2a8f28
Add sort to shared prefs tool
KCeh Jul 7, 2024
f95f4db
Extract log date time format
KCeh Jul 8, 2024
01ea4b1
Add sort to list of shared prefs files
KCeh Jul 9, 2024
819fc77
Add option to expand/hide certain shared prefs file
KCeh Jul 9, 2024
e703f41
Improve shared prefs option UX
KCeh Jul 9, 2024
8cfbc20
Improve readability of code
KCeh Jul 10, 2024
59eeb85
Merge pull request #72 from infinum/feature/sort-shared-preferences
KCeh Jul 12, 2024
97cba0f
Merge branch 'develop' into feature/Parse-UNIX-timestamp-to-readable-…
KCeh Jul 12, 2024
1a5116c
Merge pull request #71 from infinum/feature/Parse-UNIX-timestamp-to-r…
KCeh Jul 12, 2024
e80a050
Add annotation to UI thread only method
KCeh Jul 14, 2024
f7666a1
Remove redundant manifest tags
KCeh Jul 14, 2024
ee6f2e0
Merge branch 'develop' into fix/investigate-initializer-errors
KCeh Jul 14, 2024
73ff9c9
Update manifest with permission to use sentinel
KCeh Jul 14, 2024
7f79a81
Reneme timber tool constants object
KCeh Jul 14, 2024
3527381
Merge pull request #73 from infinum/fix/Exported-component-access-sho…
KCeh Jul 17, 2024
c023224
Merge branch 'develop' of https://github.com/infinum/android-sentinel…
KCeh Jul 17, 2024
8e5998d
Remove unnecessary work manager initialization
KCeh Jul 17, 2024
337d91f
Typo fix
KCeh Jul 17, 2024
fbdf3a9
Replace failure result with exception
KCeh Jul 17, 2024
bbd0d8a
Improve DI setup for work manager
KCeh Jul 17, 2024
0aa90fa
Merge pull request #69 from infinum/fix/investigate-initializer-errors
KCeh Jul 18, 2024
1d22f19
Bump version to 1.4.0
KCeh Jul 18, 2024
cec47bc
Merge pull request #74 from infinum/release/1.4.0
KCeh Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
```
Expand Down
4 changes: 2 additions & 2 deletions config.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
def major = 1
def minor = 3
def patch = 3
def minor = 4
def patch = 0

buildConfig = [
"minSdk" : 21,
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
16 changes: 5 additions & 11 deletions sentinel/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<permission
android:name="com.infinum.sentinel.permission.ACCESS_SENTINEL"
android:protectionLevel="signature" />

<application>

<activity
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">
<meta-data
Expand Down Expand Up @@ -114,17 +119,6 @@
android:value="androidx.startup" />
</provider>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ package com.infinum.sentinel.data.models.raw

internal data class PreferencesData(
val name: String,
val values: List<Triple<PreferenceType, String, Any>>
val values: List<Triple<PreferenceType, String, Any>>,
val isSortedAscending: Boolean = false,
val isExpanded: Boolean = true,
)
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal object LibraryComponents {
tools.filterIsInstance<CertificateTool>().firstOrNull()?.userCertificates.orEmpty(),
onTriggered
)
WorkManagerInitializer.init(domainComponent)
domainComponent.setup()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import com.infinum.sentinel.ui.bundles.callbacks.BundleMonitorNotificationCallba
import com.infinum.sentinel.ui.bundles.details.BundleDetailsActivity
import com.infinum.sentinel.ui.certificates.observer.CertificatesObserver
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
Expand Down Expand Up @@ -91,8 +90,6 @@ internal abstract class DomainComponent(

abstract val sentinelAnrObserver: SentinelAnrObserver

abstract val sentinelWorkerFactory: SentinelWorkerFactory

abstract val sentinelWorkManager: SentinelWorkManager

abstract val sentinelAnrObserverRunnable: SentinelAnrObserverRunnable
Expand Down Expand Up @@ -157,15 +154,10 @@ internal abstract class DomainComponent(
fun sentinelAnrObserverRunnable(dao: CrashesDao): SentinelAnrObserverRunnable =
SentinelAnrObserverRunnable(context, notificationFactory, dao)

@Provides
@DomainScope
fun sentinelWorkerFactory(): SentinelWorkerFactory =
SentinelWorkerFactory(collectors, notificationFactory)

@Provides
@DomainScope
fun sentinelWorkManager(): SentinelWorkManager =
SentinelWorkManager(context, sentinelWorkerFactory)
SentinelWorkManager(context)

@Provides
@DomainScope
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.infinum.sentinel.ui.certificates.observer

import android.content.Context
import androidx.annotation.UiThread
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

/**
* 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 delegatedWorker = delegateWorkerFactory?.createWorker(appContext, workerClassName, parameters)

override fun startWork(): ListenableFuture<Result> {
return if (delegatedWorker != null) {
delegatedWorker.startWork()
} else {
val errorMessage = "No delegateWorker available for $workerId" +
" with workerClassName of $workerClassName. Is the " +
"DelegateWorker.workerFactories populated correctly?"
throw IllegalStateException(errorMessage)
}
}

companion object {
const val DELEGATE_WORKER_ID = "com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker"

val workerFactories = object : AbstractMutableMap<String, WorkerFactory>() {

private val backingWorkerMap = mutableMapOf<String, WorkerFactory>()

@UiThread
override fun put(key: String, value: WorkerFactory): WorkerFactory? {
return backingWorkerMap.put(key, value)
}

override val entries: MutableSet<MutableMap.MutableEntry<String, WorkerFactory>>
get() = backingWorkerMap.entries
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ 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
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
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
Expand All @@ -28,44 +28,34 @@ import me.tatarka.inject.annotations.Inject
@Inject
internal class SentinelWorkManager(
private val context: Context,
private val workerFactory: WorkerFactory
) {

companion object {
private const val DEBUG_INTERVAL = 15L
private const val RELEASE_INTERVAL = 1440L
}

init {
WorkManager.initialize(
context,
Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.setWorkerFactory(workerFactory)
.build()
)
}

@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<CertificateCheckWorker>(
PeriodicWorkRequestBuilder<DelegateWorker>(
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)
Expand All @@ -80,6 +70,7 @@ internal class SentinelWorkManager(
)
.build()
)
}

fun certificatesCheckState(): Flow<Boolean> =
WorkManager.getInstance(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,32 +64,51 @@ internal class PreferencesFragment :
}
}

@Suppress("UNCHECKED_CAST")
private fun createItemView(data: PreferencesData): View =
SentinelViewItemPreferenceBinding.inflate(layoutInflater, binding.contentLayout, false)
.apply {
nameView.text = data.name
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
)
sortImageView.setOnClickListener {
viewModel.onSortClicked(data)
}
hideExpandImageView.setOnClickListener {
viewModel.onHideExpandClicked(data)
}

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

private fun SentinelViewItemPreferenceBinding.showPreferenceData(data: PreferencesData) {
data.values.forEach { (preferenceType, label, value) ->
prefsLayout.addView(
SentinelViewItemTextBinding.inflate(layoutInflater, prefsLayout, false)
.apply {
labelView.isAllCaps = false
labelView.text = label
valueView.text = value.toString()
root.setOnClickListener { _ ->
viewModel.cache(
name = data.name,
tuple = Triple(preferenceType, label, value)
)
}
root.setOnLongClickListener {
it.context.copyToClipboard(
key = label,
value = value.toString()
)
}
}.root
)
}
}
}
Loading
Loading