diff --git a/CHANGELOG.md b/CHANGELOG.md index 82f6926d..4e7dca91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Change Log ========== +## Version 1.2.4 + +_2023-04-03_ + +* Replace Koin with Kotlin Inject. +* Filter out non Bundle keys in Bundle size monitor. +* Add support for explicit trigger declarations in manifest. + ## Version 1.2.3 _2023-03-21_ diff --git a/README.md b/README.md index 8ef8a836..52ac52b2 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 -debugImplementation "com.infinum.sentinel:sentinel:1.2.3" -releaseImplementation "com.infinum.sentinel:sentinel-no-op:1.2.3" +debugImplementation "com.infinum.sentinel:sentinel:1.2.4" +releaseImplementation "com.infinum.sentinel:sentinel-no-op:1.2.4" ``` **KotlinDSL** ```kotlin -debugImplementation("com.infinum.sentinel:sentinel:1.2.3") -releaseImplementation("com.infinum.sentinel:sentinel-no-op:1.2.3") +debugImplementation("com.infinum.sentinel:sentinel:1.2.4") +releaseImplementation("com.infinum.sentinel:sentinel-no-op:1.2.4") ``` Basic tools are provided inside the main package but depending on requirements you might want to add @@ -74,27 +74,27 @@ specific tools: **Groovy** ```groovy -debugImplementation "com.infinum.sentinel:tool-chucker:1.2.3" -debugImplementation "com.infinum.sentinel:tool-collar:1.2.3" -debugImplementation "com.infinum.sentinel:tool-dbinspector:1.2.3" -debugImplementation "com.infinum.sentinel:tool-leakcanary:1.2.3" -debugImplementation "com.infinum.sentinel:tool-appgallery:1.2.3" -debugImplementation "com.infinum.sentinel:tool-googleplay:1.2.3" -debugImplementation "com.infinum.sentinel:tool-thimble:1.2.3" -debugImplementation "com.infinum.sentinel:tool-timber:1.2.3" +debugImplementation "com.infinum.sentinel:tool-chucker:1.2.4" +debugImplementation "com.infinum.sentinel:tool-collar:1.2.4" +debugImplementation "com.infinum.sentinel:tool-dbinspector:1.2.4" +debugImplementation "com.infinum.sentinel:tool-leakcanary:1.2.4" +debugImplementation "com.infinum.sentinel:tool-appgallery:1.2.4" +debugImplementation "com.infinum.sentinel:tool-googleplay:1.2.4" +debugImplementation "com.infinum.sentinel:tool-thimble:1.2.4" +debugImplementation "com.infinum.sentinel:tool-timber:1.2.4" ``` **KotlinDSL** ```kotlin -debugImplementation("com.infinum.sentinel:tool-chucker:1.2.3") -debugImplementation("com.infinum.sentinel:tool-collar:1.2.3") -debugImplementation("com.infinum.sentinel:tool-dbinspector:1.2.3") -debugImplementation("com.infinum.sentinel:tool-leakcanary:1.2.3") -debugImplementation("com.infinum.sentinel:tool-appgallery:1.2.3") -debugImplementation("com.infinum.sentinel:tool-googleplay:1.2.3") -debugImplementation("com.infinum.sentinel:tool-thimble:1.2.3") -debugImplementation("com.infinum.sentinel:tool-timber:1.2.3") +debugImplementation("com.infinum.sentinel:tool-chucker:1.2.4") +debugImplementation("com.infinum.sentinel:tool-collar:1.2.4") +debugImplementation("com.infinum.sentinel:tool-dbinspector:1.2.4") +debugImplementation("com.infinum.sentinel:tool-leakcanary:1.2.4") +debugImplementation("com.infinum.sentinel:tool-appgallery:1.2.4") +debugImplementation("com.infinum.sentinel:tool-googleplay:1.2.4") +debugImplementation("com.infinum.sentinel:tool-thimble:1.2.4") +debugImplementation("com.infinum.sentinel:tool-timber:1.2.4") ``` Now you can sync your project. @@ -194,7 +194,46 @@ _Sentinel_ observes several different trigger events, determining when to show u *Manual* trigger cannot be turned off but rest are configurable through _Sentinel_ settings except *Foreground* trigger when running on emulators. Trigger states will be persisted between sessions. -*Upon first run, all triggers are enabled.* +*Upon first run, all triggers are enabled.* +Only way to override default trigger behaviour is to explicitly set them in you application manifest. +If declared, these will override any changes that user does on each application launch. +Accepted values are *0* and *1* to disable or enable a trigger. +Anything else will result in the same way like the metadata key isn't declared at all. +```xml + + + ... + + + + + + + + + + + + ... + + +``` - `Manual` - used for manually triggering UI with _show()_ - `Shake` - default trigger to show UI, shake device to invoke diff --git a/config.gradle b/config.gradle index 0e441dd4..ac125a10 100644 --- a/config.gradle +++ b/config.gradle @@ -1,13 +1,13 @@ ext { def major = 1 def minor = 2 - def patch = 3 + def patch = 4 buildConfig = [ "minSdk" : 21, "compileSdk": 33, "targetSdk" : 33, - "buildTools": "33.0.0" + "buildTools": "33.0.2" ] releaseConfig = [ "group" : "com.infinum.sentinel", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 155a2efa..59ebf9d6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] -sentinel = "1.2.3" +sentinel = "1.2.4" gradle = "7.4.2" -desugar = "1.2.2" +desugar = "2.0.2" kotlin = "1.8.10" coroutines = "1.6.4" json = "1.5.0" @@ -18,7 +18,7 @@ startup = "1.1.1" crypto = "1.1.0-alpha05" dynamicanimation = "1.0.0" design = "1.8.0" -koin = "3.3.3" +inject = "0.6.1" timber = "5.0.1" detekt = "1.21.0" ktlintplugin = "10.3.0" @@ -26,7 +26,7 @@ ktlint = "0.45.2" cpd = "3.2" dokka = "1.8.10" chucker = "3.5.2" -collar = "1.3.7" +collar = "1.4.0" dbinspector = "5.4.9" leakcanary = "2.10" thimble = "1.0.1" @@ -75,7 +75,8 @@ androidx-workmanager-ktx = { module = "androidx.work:work-runtime-ktx", version. material = { module = "com.google.android.material:material", version.ref = "design" } -koin = { module = "io.insert-koin:koin-android", version.ref = "koin" } +inject-compiler = { module = "me.tatarka.inject:kotlin-inject-compiler-ksp", version.ref = "inject" } +inject-runtime = { module = "me.tatarka.inject:kotlin-inject-runtime", version.ref = "inject" } detekt-gradle = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } diff --git a/sample/build.gradle b/sample/build.gradle index bdcac7fa..da924821 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -69,6 +69,7 @@ dependencies { implementation libs.timber debugImplementation libs.library +// debugImplementation project(":sentinel") releaseImplementation libs.librarynoop debugImplementation libs.bundles.tools diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index f19aa492..82041cbd 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:replace="android:theme,android:name,android:supportsRtl"> + diff --git a/sentinel/build.gradle b/sentinel/build.gradle index 0652fbc1..157f4095 100644 --- a/sentinel/build.gradle +++ b/sentinel/build.gradle @@ -94,7 +94,8 @@ dependencies { implementation libs.bundles.androidx ksp libs.androidx.room.compiler implementation libs.material - implementation libs.koin + ksp libs.inject.compiler + implementation libs.inject.runtime androidTestImplementation "junit:junit:4.13.2" androidTestImplementation "androidx.arch.core:core-testing:2.1.0" @@ -114,6 +115,10 @@ dependencies { testImplementation "androidx.test.ext:junit:1.1.3" } +ksp { + arg("me.tatarka.inject.dumpGraph", "false") +} + apply from: "publish.gradle" project.gradle.taskGraph.whenReady { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/Sentinel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/Sentinel.kt index 3c83750a..f113caaf 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/Sentinel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/Sentinel.kt @@ -5,8 +5,8 @@ import androidx.annotation.DrawableRes import androidx.annotation.StringRes import com.infinum.sentinel.data.models.local.crash.ProcessThread import com.infinum.sentinel.data.models.memory.triggers.manual.ManualTrigger +import com.infinum.sentinel.di.LibraryComponents import com.infinum.sentinel.extensions.asStringArray -import com.infinum.sentinel.ui.Presentation import java.io.ByteArrayOutputStream import java.io.PrintStream import java.util.Locale @@ -16,7 +16,7 @@ public object Sentinel { @JvmStatic @JvmOverloads public fun watch(tools: Set = setOf()): Sentinel { - Presentation.setup(tools) { Presentation.show() } + LibraryComponents.setup(tools) { LibraryComponents.presentation().show() } return this } @@ -25,11 +25,11 @@ public object Sentinel { @JvmStatic public fun setExceptionHandler(handler: Thread.UncaughtExceptionHandler?): Unit = - Presentation.setExceptionHandler(handler) + LibraryComponents.presentation().setExceptionHandler(handler) @JvmStatic public fun setAnrListener(listener: ApplicationNotRespondingListener?): Unit = - Presentation.setAnrListener(listener) + LibraryComponents.presentation().setAnrListener(listener) /** * Used for manually showing Sentinel UI @@ -37,7 +37,7 @@ public object Sentinel { private fun showInternal() { val manualTrigger = ManualTrigger() if (manualTrigger.active) { - Presentation.show() + LibraryComponents.presentation().show() } } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/SentinelInitializer.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/SentinelInitializer.kt index 1e2ec907..444fcae9 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/SentinelInitializer.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/SentinelInitializer.kt @@ -2,16 +2,13 @@ package com.infinum.sentinel import android.content.Context import androidx.startup.Initializer -import com.infinum.sentinel.di.LibraryKoin -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.di.LibraryComponents internal class SentinelInitializer : Initializer> { override fun create(context: Context): Class { - LibraryKoin.initialize(context) - - Presentation.initialize(context) + LibraryComponents.initialize(context) return SentinelInitializer::class.java } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/Data.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/Data.kt deleted file mode 100644 index bbe96f90..00000000 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/Data.kt +++ /dev/null @@ -1,140 +0,0 @@ -package com.infinum.sentinel.data - -import android.content.Context -import androidx.room.Room -import androidx.room.RoomDatabase -import com.infinum.sentinel.Sentinel -import com.infinum.sentinel.data.models.memory.triggers.airplanemode.AirplaneModeOnTrigger -import com.infinum.sentinel.data.models.memory.triggers.foreground.ForegroundTrigger -import com.infinum.sentinel.data.models.memory.triggers.manual.ManualTrigger -import com.infinum.sentinel.data.models.memory.triggers.proximity.ProximityTrigger -import com.infinum.sentinel.data.models.memory.triggers.shake.ShakeTrigger -import com.infinum.sentinel.data.models.memory.triggers.usb.UsbConnectedTrigger -import com.infinum.sentinel.data.sources.local.room.SentinelDatabase -import com.infinum.sentinel.data.sources.local.room.callbacks.SentinelDefaultValuesCallback -import com.infinum.sentinel.data.sources.memory.bundles.BundlesCache -import com.infinum.sentinel.data.sources.memory.bundles.InMemoryBundlesCache -import com.infinum.sentinel.data.sources.memory.certificate.CertificateCache -import com.infinum.sentinel.data.sources.memory.certificate.InMemoryCertificateCache -import com.infinum.sentinel.data.sources.memory.preference.InMemoryPreferenceCache -import com.infinum.sentinel.data.sources.memory.preference.PreferenceCache -import com.infinum.sentinel.data.sources.memory.triggers.TriggersCache -import com.infinum.sentinel.data.sources.memory.triggers.TriggersCacheFactory -import com.infinum.sentinel.data.sources.raw.collectors.ApplicationCollector -import com.infinum.sentinel.data.sources.raw.collectors.CertificateCollector -import com.infinum.sentinel.data.sources.raw.collectors.DeviceCollector -import com.infinum.sentinel.data.sources.raw.collectors.PermissionsCollector -import com.infinum.sentinel.data.sources.raw.collectors.PreferencesCollector -import com.infinum.sentinel.data.sources.raw.collectors.ToolsCollector -import com.infinum.sentinel.data.sources.raw.formatters.HtmlFormatter -import com.infinum.sentinel.data.sources.raw.formatters.JsonFormatter -import com.infinum.sentinel.data.sources.raw.formatters.MarkdownFormatter -import com.infinum.sentinel.data.sources.raw.formatters.PlainFormatter -import com.infinum.sentinel.data.sources.raw.formatters.XmlFormatter -import com.infinum.sentinel.domain.collectors.Collectors -import com.infinum.sentinel.domain.formatters.Formatters -import java.security.cert.X509Certificate -import java.util.Locale -import org.koin.core.module.Module -import org.koin.core.qualifier.StringQualifier -import org.koin.dsl.module - -internal object Data { - - const val DATABASE_VERSION = 5 - - object Qualifiers { - - object Name { - val LAMBDA_TRIGGER = StringQualifier("data.qualifiers.name.lambda.trigger") - val DATABASE = StringQualifier("data.qualifiers.name.database") - } - } - - private var onTriggered: () -> Unit = {} - - fun setup(onTriggered: () -> Unit) { - this.onTriggered = onTriggered - } - - fun modules(): List = - listOf( - memory(), - local(), - raw() - ) - - private fun local() = module { - single { SentinelDefaultValuesCallback() } - single(qualifier = Qualifiers.Name.DATABASE) { - val context: Context = get() - String.format( - Locale.getDefault(), - "sentinel_%s_v%s.db", - context.applicationContext - .packageName - .replace(".", "_") - .lowercase(Locale.getDefault()), - DATABASE_VERSION - ) - } - single { - Room.databaseBuilder( - get(), - SentinelDatabase::class.java, - get(Qualifiers.Name.DATABASE) - ) - .setJournalMode(RoomDatabase.JournalMode.TRUNCATE) - .fallbackToDestructiveMigration() - .addCallback(get()) - .build() - } - single { get().triggers() } - single { get().formats() } - single { get().bundleMonitor() } - single { get().crashes() } - single { get().crashMonitor() } - single { get().certificateMonitor() } - } - - private fun raw() = module { - single { DeviceCollector(get()) } - single { ApplicationCollector(get()) } - single { PermissionsCollector(get()) } - single { PreferencesCollector(get()) } - single { (managers: List) -> CertificateCollector(managers) } - single { (tools: Set) -> ToolsCollector(tools) } - - single { PlainFormatter(get(), get(), get(), get(), get()) } - single { MarkdownFormatter(get(), get(), get(), get(), get()) } - single { JsonFormatter(get(), get(), get(), get(), get()) } - single { XmlFormatter(get(), get(), get(), get(), get()) } - single { HtmlFormatter(get(), get(), get(), get(), get()) } - } - - private fun memory() = module { - single(qualifier = Qualifiers.Name.LAMBDA_TRIGGER) { onTriggered } - - single { ManualTrigger() } - single { ForegroundTrigger(get(qualifier = Qualifiers.Name.LAMBDA_TRIGGER)) } - single { ShakeTrigger(get(), get(qualifier = Qualifiers.Name.LAMBDA_TRIGGER)) } - single { ProximityTrigger(get(), get(qualifier = Qualifiers.Name.LAMBDA_TRIGGER)) } - single { UsbConnectedTrigger(get(), get(qualifier = Qualifiers.Name.LAMBDA_TRIGGER)) } - single { AirplaneModeOnTrigger(get(), get(qualifier = Qualifiers.Name.LAMBDA_TRIGGER)) } - - single { - TriggersCacheFactory( - get(), - get(), - get(), - get(), - get(), - get() - ) - } - - single { InMemoryBundlesCache() } - single { InMemoryPreferenceCache() } - single { InMemoryCertificateCache() } - } -} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/airplanemode/AirplaneModeOnTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/airplanemode/AirplaneModeOnTrigger.kt index 9855eef3..c952ccd8 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/airplanemode/AirplaneModeOnTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/airplanemode/AirplaneModeOnTrigger.kt @@ -4,7 +4,9 @@ import android.content.Context import android.content.Intent import com.infinum.sentinel.data.models.memory.triggers.shared.BroadcastReceiverTrigger import com.infinum.sentinel.data.models.memory.triggers.shared.receiver.BroadcastReceiver +import me.tatarka.inject.annotations.Inject +@Inject internal class AirplaneModeOnTrigger( context: Context, private val trigger: () -> Unit diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/foreground/ForegroundTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/foreground/ForegroundTrigger.kt index 9ed34781..921b1c54 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/foreground/ForegroundTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/foreground/ForegroundTrigger.kt @@ -1,7 +1,9 @@ package com.infinum.sentinel.data.models.memory.triggers.foreground import com.infinum.sentinel.data.models.memory.triggers.shared.AbstractTrigger +import me.tatarka.inject.annotations.Inject +@Inject internal class ForegroundTrigger( private val trigger: () -> Unit ) : AbstractTrigger() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/manual/ManualTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/manual/ManualTrigger.kt index 14d42d19..2296712c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/manual/ManualTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/manual/ManualTrigger.kt @@ -1,7 +1,9 @@ package com.infinum.sentinel.data.models.memory.triggers.manual import com.infinum.sentinel.data.models.memory.triggers.shared.AbstractTrigger +import me.tatarka.inject.annotations.Inject +@Inject internal class ManualTrigger : AbstractTrigger() { init { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/proximity/ProximityTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/proximity/ProximityTrigger.kt index d501d50b..b00be045 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/proximity/ProximityTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/proximity/ProximityTrigger.kt @@ -4,7 +4,9 @@ import android.content.Context import android.hardware.Sensor import android.hardware.SensorEvent import com.infinum.sentinel.data.models.memory.triggers.shared.SensorTrigger +import me.tatarka.inject.annotations.Inject +@Inject internal class ProximityTrigger( context: Context, trigger: () -> Unit diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/shake/ShakeTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/shake/ShakeTrigger.kt index 1419c172..5adf9ec0 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/shake/ShakeTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/shake/ShakeTrigger.kt @@ -5,7 +5,9 @@ import android.hardware.Sensor import android.hardware.SensorEvent import com.infinum.sentinel.data.models.memory.triggers.shared.SensorTrigger import com.infinum.sentinel.data.models.memory.triggers.shared.samples.SampleQueue +import me.tatarka.inject.annotations.Inject +@Inject internal class ShakeTrigger( context: Context, trigger: () -> Unit diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/usb/UsbConnectedTrigger.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/usb/UsbConnectedTrigger.kt index e193288a..e14ee46a 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/usb/UsbConnectedTrigger.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/models/memory/triggers/usb/UsbConnectedTrigger.kt @@ -3,7 +3,9 @@ package com.infinum.sentinel.data.models.memory.triggers.usb import android.content.Context import com.infinum.sentinel.data.models.memory.triggers.shared.BroadcastReceiverTrigger import com.infinum.sentinel.data.models.memory.triggers.shared.receiver.BroadcastReceiver +import me.tatarka.inject.annotations.Inject +@Inject internal class UsbConnectedTrigger( context: Context, private val trigger: () -> Unit diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/SentinelDatabase.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/SentinelDatabase.kt index 2585162e..c9ca5ce3 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/SentinelDatabase.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/SentinelDatabase.kt @@ -3,7 +3,6 @@ package com.infinum.sentinel.data.sources.local.room import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters -import com.infinum.sentinel.data.Data.DATABASE_VERSION import com.infinum.sentinel.data.models.local.BundleMonitorEntity import com.infinum.sentinel.data.models.local.CertificateMonitorEntity import com.infinum.sentinel.data.models.local.CrashEntity @@ -20,6 +19,7 @@ import com.infinum.sentinel.data.sources.local.room.typeconverters.ChronoUnitCon import com.infinum.sentinel.data.sources.local.room.typeconverters.CrashDataConverter import com.infinum.sentinel.data.sources.local.room.typeconverters.FormatTypeConverter import com.infinum.sentinel.data.sources.local.room.typeconverters.TriggerTypeConverter +import com.infinum.sentinel.di.LibraryComponents.DATABASE_VERSION @Database( entities = [ diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/callbacks/SentinelDefaultValuesCallback.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/callbacks/SentinelDefaultValuesCallback.kt index dcb44c57..19ed75d7 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/callbacks/SentinelDefaultValuesCallback.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/local/room/callbacks/SentinelDefaultValuesCallback.kt @@ -2,7 +2,9 @@ package com.infinum.sentinel.data.sources.local.room.callbacks import androidx.room.RoomDatabase import androidx.sqlite.db.SupportSQLiteDatabase +import me.tatarka.inject.annotations.Inject +@Inject internal class SentinelDefaultValuesCallback : RoomDatabase.Callback() { companion object { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/bundles/InMemoryBundlesCache.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/bundles/InMemoryBundlesCache.kt index 91c341ec..d5e49ac5 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/bundles/InMemoryBundlesCache.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/bundles/InMemoryBundlesCache.kt @@ -4,7 +4,9 @@ import com.infinum.sentinel.domain.bundle.descriptor.models.BundleDescriptor import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asSharedFlow +import me.tatarka.inject.annotations.Inject +@Inject internal class InMemoryBundlesCache : BundlesCache { private val descriptors = mutableListOf() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/certificate/InMemoryCertificateCache.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/certificate/InMemoryCertificateCache.kt index 4012b751..97e2c121 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/certificate/InMemoryCertificateCache.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/certificate/InMemoryCertificateCache.kt @@ -1,7 +1,9 @@ package com.infinum.sentinel.data.sources.memory.certificate import com.infinum.sentinel.data.models.raw.CertificateData +import me.tatarka.inject.annotations.Inject +@Inject internal class InMemoryCertificateCache : CertificateCache { private var value: CertificateData? = null diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/preference/InMemoryPreferenceCache.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/preference/InMemoryPreferenceCache.kt index 0860b26c..c91da937 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/preference/InMemoryPreferenceCache.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/preference/InMemoryPreferenceCache.kt @@ -1,7 +1,9 @@ package com.infinum.sentinel.data.sources.memory.preference import com.infinum.sentinel.data.models.raw.PreferenceType +import me.tatarka.inject.annotations.Inject +@Inject internal class InMemoryPreferenceCache : PreferenceCache { private var name: String? = null diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/triggers/TriggersCacheFactory.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/triggers/TriggersCacheFactory.kt index bdd42e45..725cdc4d 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/triggers/TriggersCacheFactory.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/memory/triggers/TriggersCacheFactory.kt @@ -6,7 +6,9 @@ import com.infinum.sentinel.data.models.memory.triggers.manual.ManualTrigger import com.infinum.sentinel.data.models.memory.triggers.proximity.ProximityTrigger import com.infinum.sentinel.data.models.memory.triggers.shake.ShakeTrigger import com.infinum.sentinel.data.models.memory.triggers.usb.UsbConnectedTrigger +import me.tatarka.inject.annotations.Inject +@Inject internal class TriggersCacheFactory( private val manual: ManualTrigger, private val foreground: ForegroundTrigger, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ApplicationCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ApplicationCollector.kt index c5fab660..ee4a04bb 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ApplicationCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ApplicationCollector.kt @@ -11,7 +11,9 @@ import com.infinum.sentinel.extensions.installerPackage import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +import me.tatarka.inject.annotations.Inject +@Inject internal class ApplicationCollector( private val context: Context ) : Collectors.Application { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/CertificateCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/CertificateCollector.kt index dbf677c5..13e8e8f2 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/CertificateCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/CertificateCollector.kt @@ -19,9 +19,12 @@ import java.security.cert.X509Certificate import java.security.interfaces.DSAPublicKey import java.security.interfaces.ECPublicKey import java.security.interfaces.RSAPublicKey +import me.tatarka.inject.annotations.Assisted +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificateCollector( - var userCertificates: List + @Assisted var userCertificates: List ) : Collectors.Certificates { companion object { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/DeviceCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/DeviceCollector.kt index 62f1cb59..2dc9c9da 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/DeviceCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/DeviceCollector.kt @@ -13,7 +13,9 @@ import com.infinum.sentinel.extensions.widthPixels import java.io.BufferedReader import java.io.File import java.io.InputStreamReader +import me.tatarka.inject.annotations.Inject +@Inject internal class DeviceCollector( private val context: Context ) : Collectors.Device { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PermissionsCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PermissionsCollector.kt index 6913f529..46c389b9 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PermissionsCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/PermissionsCollector.kt @@ -5,7 +5,9 @@ import android.content.pm.PackageManager import android.os.Build import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.extensions.isPermissionGranted +import me.tatarka.inject.annotations.Inject +@Inject internal class PermissionsCollector( private val context: Context ) : Collectors.Permissions { 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 e208a9c9..882f71cf 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 @@ -7,7 +7,9 @@ import com.infinum.sentinel.data.models.raw.PreferenceType import com.infinum.sentinel.data.models.raw.PreferencesData import com.infinum.sentinel.domain.collectors.Collectors import java.io.File +import me.tatarka.inject.annotations.Inject +@Inject internal class PreferencesCollector( private val context: Context ) : Collectors.Preferences { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ToolsCollector.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ToolsCollector.kt index 0c8fc7c8..386a8c14 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ToolsCollector.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/collectors/ToolsCollector.kt @@ -2,9 +2,12 @@ package com.infinum.sentinel.data.sources.raw.collectors import com.infinum.sentinel.Sentinel import com.infinum.sentinel.domain.collectors.Collectors +import me.tatarka.inject.annotations.Assisted +import me.tatarka.inject.annotations.Inject +@Inject internal class ToolsCollector( - private val tools: Set + @Assisted private val tools: Set ) : Collectors.Tools { override fun invoke() = diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/HtmlFormatter.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/HtmlFormatter.kt index 04777e66..05a5fa20 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/HtmlFormatter.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/HtmlFormatter.kt @@ -11,7 +11,9 @@ import com.infinum.sentinel.data.sources.raw.formatters.Formatter.Companion.PREF import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.domain.formatters.Formatters import com.infinum.sentinel.extensions.sanitize +import me.tatarka.inject.annotations.Inject +@Inject internal class HtmlFormatter( private val context: Context, private val applicationCollector: Collectors.Application, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/JsonFormatter.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/JsonFormatter.kt index 4b60d1ad..db160a80 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/JsonFormatter.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/JsonFormatter.kt @@ -15,10 +15,12 @@ import com.infinum.sentinel.data.sources.raw.formatters.Formatter.Companion.VALU import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.domain.formatters.Formatters import com.infinum.sentinel.extensions.sanitize +import me.tatarka.inject.annotations.Inject import org.json.JSONArray import org.json.JSONObject @Suppress("TooManyFunctions") +@Inject internal class JsonFormatter( private val context: Context, private val applicationCollector: Collectors.Application, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/MarkdownFormatter.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/MarkdownFormatter.kt index bde64df3..be0d7e75 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/MarkdownFormatter.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/MarkdownFormatter.kt @@ -12,7 +12,9 @@ import com.infinum.sentinel.data.sources.raw.formatters.shared.StringBuilderForm import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.domain.formatters.Formatters import com.infinum.sentinel.extensions.sanitize +import me.tatarka.inject.annotations.Inject +@Inject internal class MarkdownFormatter( private val context: Context, private val applicationCollector: Collectors.Application, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/PlainFormatter.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/PlainFormatter.kt index 8558ee2b..fbae756a 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/PlainFormatter.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/PlainFormatter.kt @@ -13,7 +13,9 @@ import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.domain.formatters.Formatters import com.infinum.sentinel.extensions.sanitize import java.util.Locale +import me.tatarka.inject.annotations.Inject +@Inject internal class PlainFormatter( private val context: Context, private val applicationCollector: Collectors.Application, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/XmlFormatter.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/XmlFormatter.kt index fb5d9d6a..c6a4415d 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/XmlFormatter.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/data/sources/raw/formatters/XmlFormatter.kt @@ -17,9 +17,11 @@ import com.infinum.sentinel.domain.collectors.Collectors import com.infinum.sentinel.domain.formatters.Formatters import com.infinum.sentinel.extensions.sanitize import java.io.StringWriter +import me.tatarka.inject.annotations.Inject import org.xmlpull.v1.XmlSerializer @Suppress("TooManyFunctions") +@Inject internal class XmlFormatter( private val context: Context, private val applicationCollector: Collectors.Application, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt new file mode 100644 index 00000000..72d71cb2 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryComponents.kt @@ -0,0 +1,51 @@ +package com.infinum.sentinel.di + +import android.annotation.SuppressLint +import android.content.Context +import com.infinum.sentinel.Sentinel +import com.infinum.sentinel.di.component.DataComponent +import com.infinum.sentinel.di.component.DomainComponent +import com.infinum.sentinel.di.component.PresentationComponent +import com.infinum.sentinel.di.component.ViewModelComponent +import com.infinum.sentinel.di.component.create +import com.infinum.sentinel.ui.tools.AppInfoTool +import com.infinum.sentinel.ui.tools.BundleMonitorTool +import com.infinum.sentinel.ui.tools.CertificateTool +import com.infinum.sentinel.ui.tools.CrashMonitorTool + +@SuppressLint("StaticFieldLeak") +internal object LibraryComponents { + + internal const val DATABASE_VERSION = 5 + + private val DEFAULT_TOOLS = setOf( + CrashMonitorTool(), + BundleMonitorTool(), + AppInfoTool() + ) + + private lateinit var dataComponent: DataComponent + private lateinit var domainComponent: DomainComponent + private lateinit var viewModelComponent: ViewModelComponent + private lateinit var presentationComponent: PresentationComponent + + fun initialize(context: Context) { + dataComponent = DataComponent::class.create(context) + domainComponent = DomainComponent::class.create(context, dataComponent) + viewModelComponent = ViewModelComponent::class.create(domainComponent) + presentationComponent = PresentationComponent::class.create(context, viewModelComponent) + } + + fun setup(tools: Set, onTriggered: () -> Unit) { + dataComponent.setup( + tools.plus(DEFAULT_TOOLS), + tools.filterIsInstance().firstOrNull()?.userCertificates.orEmpty(), + onTriggered + ) + domainComponent.setup() + } + + fun presentation(): PresentationComponent = presentationComponent + + fun viewModels(): ViewModelComponent = viewModelComponent +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoin.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoin.kt deleted file mode 100644 index c276aadc..00000000 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoin.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.infinum.sentinel.di - -import android.content.Context -import com.infinum.sentinel.ui.Presentation -import org.koin.android.ext.koin.androidContext -import org.koin.android.ext.koin.androidLogger -import org.koin.core.Koin -import org.koin.core.KoinApplication -import org.koin.core.logger.Level - -internal object LibraryKoin { - - private val koinApplication = KoinApplication.init() - - fun koin(): Koin = koinApplication.koin - - fun initialize(context: Context) { - koinApplication.apply { - androidLogger(Level.ERROR) - androidContext(context) - modules(Presentation.modules()) - } - } -} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoinComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoinComponent.kt deleted file mode 100644 index 8715fc6e..00000000 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/di/LibraryKoinComponent.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.infinum.sentinel.di - -import org.koin.core.Koin -import org.koin.core.component.KoinComponent - -internal interface LibraryKoinComponent : KoinComponent { - - override fun getKoin(): Koin = - LibraryKoin.koin() -} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DataComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DataComponent.kt new file mode 100644 index 00000000..87ceec91 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DataComponent.kt @@ -0,0 +1,332 @@ +package com.infinum.sentinel.di.component + +import android.content.Context +import androidx.room.Room +import androidx.room.RoomDatabase +import com.infinum.sentinel.Sentinel +import com.infinum.sentinel.data.models.memory.triggers.airplanemode.AirplaneModeOnTrigger +import com.infinum.sentinel.data.models.memory.triggers.foreground.ForegroundTrigger +import com.infinum.sentinel.data.models.memory.triggers.manual.ManualTrigger +import com.infinum.sentinel.data.models.memory.triggers.proximity.ProximityTrigger +import com.infinum.sentinel.data.models.memory.triggers.shake.ShakeTrigger +import com.infinum.sentinel.data.models.memory.triggers.usb.UsbConnectedTrigger +import com.infinum.sentinel.data.sources.local.room.SentinelDatabase +import com.infinum.sentinel.data.sources.local.room.callbacks.SentinelDefaultValuesCallback +import com.infinum.sentinel.data.sources.local.room.dao.BundleMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CertificateMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CrashMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CrashesDao +import com.infinum.sentinel.data.sources.local.room.dao.FormatsDao +import com.infinum.sentinel.data.sources.local.room.dao.TriggersDao +import com.infinum.sentinel.data.sources.memory.bundles.BundlesCache +import com.infinum.sentinel.data.sources.memory.bundles.InMemoryBundlesCache +import com.infinum.sentinel.data.sources.memory.certificate.CertificateCache +import com.infinum.sentinel.data.sources.memory.certificate.InMemoryCertificateCache +import com.infinum.sentinel.data.sources.memory.preference.InMemoryPreferenceCache +import com.infinum.sentinel.data.sources.memory.preference.PreferenceCache +import com.infinum.sentinel.data.sources.memory.triggers.TriggersCache +import com.infinum.sentinel.data.sources.memory.triggers.TriggersCacheFactory +import com.infinum.sentinel.data.sources.raw.collectors.ApplicationCollector +import com.infinum.sentinel.data.sources.raw.collectors.CertificateCollector +import com.infinum.sentinel.data.sources.raw.collectors.DeviceCollector +import com.infinum.sentinel.data.sources.raw.collectors.PermissionsCollector +import com.infinum.sentinel.data.sources.raw.collectors.PreferencesCollector +import com.infinum.sentinel.data.sources.raw.collectors.ToolsCollector +import com.infinum.sentinel.data.sources.raw.formatters.HtmlFormatter +import com.infinum.sentinel.data.sources.raw.formatters.JsonFormatter +import com.infinum.sentinel.data.sources.raw.formatters.MarkdownFormatter +import com.infinum.sentinel.data.sources.raw.formatters.PlainFormatter +import com.infinum.sentinel.data.sources.raw.formatters.XmlFormatter +import com.infinum.sentinel.di.LibraryComponents +import com.infinum.sentinel.di.scope.DataScope +import com.infinum.sentinel.domain.collectors.Collectors +import com.infinum.sentinel.domain.formatters.Formatters +import java.security.cert.X509Certificate +import java.util.Locale +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Inject +import me.tatarka.inject.annotations.Provides + +@Suppress("TooManyFunctions") +@Component +@DataScope +internal abstract class DataComponent( + private val context: Context +) { + private var tools: Set = setOf() + private var userCertificates: List = listOf() + private var onTriggered: () -> Unit = {} + + fun setup( + tools: Set, + userCertificates: List, + onTriggered: () -> Unit + ) { + this.tools = tools + this.userCertificates = userCertificates + this.onTriggered = onTriggered + } + + //region Local + abstract val database: SentinelDatabase + + abstract val callback: RoomDatabase.Callback + + abstract val triggersDao: TriggersDao + + abstract val formatsDao: FormatsDao + + abstract val bundleMonitorDao: BundleMonitorDao + + abstract val crashesDao: CrashesDao + + abstract val crashMonitorDao: CrashMonitorDao + + abstract val certificateMonitorDao: CertificateMonitorDao + + @Provides + @DataScope + fun callback(): RoomDatabase.Callback = SentinelDefaultValuesCallback() + + @Provides + @Inject + @DataScope + fun database(): SentinelDatabase = + Room.databaseBuilder( + context, + SentinelDatabase::class.java, + String.format( + Locale.getDefault(), + "sentinel_%s_v%s.db", + context.applicationContext + .packageName + .replace(".", "_") + .lowercase(Locale.getDefault()), + LibraryComponents.DATABASE_VERSION + ) + ) + .setJournalMode(RoomDatabase.JournalMode.TRUNCATE) + .fallbackToDestructiveMigration() + .addCallback(callback) + .build() + + @Provides + @DataScope + fun triggers(): TriggersDao = + database.triggers() + + @Provides + @DataScope + fun formats(): FormatsDao = + database.formats() + + @Provides + @DataScope + fun bundleMonitor(): BundleMonitorDao = + database.bundleMonitor() + + @Provides + @DataScope + fun crashes(): CrashesDao = + database.crashes() + + @Provides + @DataScope + fun crashMonitor(): CrashMonitorDao = + database.crashMonitor() + + @Provides + @DataScope + fun certificateMonitor(): CertificateMonitorDao = + database.certificateMonitor() + + //endregion + + //region Raw + abstract val deviceCollector: Collectors.Device + + abstract val applicationCollector: Collectors.Application + + abstract val permissionsCollector: Collectors.Permissions + + abstract val preferencesCollector: Collectors.Preferences + + abstract val certificatesCollector: Collectors.Certificates + + abstract val toolsCollector: Collectors.Tools + + abstract val plainFormatter: Formatters.Plain + + abstract val markdownFormatter: Formatters.Markdown + + abstract val jsonFormatter: Formatters.Json + + abstract val xmlFormatter: Formatters.Xml + + abstract val htmlFormatter: Formatters.Html + + @Provides + @DataScope + fun deviceCollector(): Collectors.Device = + DeviceCollector(context) + + @Provides + @DataScope + fun applicationCollector(): Collectors.Application = + ApplicationCollector(context) + + @Provides + @DataScope + fun permissionsCollector(): Collectors.Permissions = + PermissionsCollector(context) + + @Provides + @DataScope + fun preferencesCollector(): Collectors.Preferences = + PreferencesCollector(context) + + @Provides + @DataScope + fun certificatesCollector(): Collectors.Certificates = + CertificateCollector(userCertificates) + + @Provides + @DataScope + fun toolsCollector(): Collectors.Tools = + ToolsCollector(tools) + + @Provides + @DataScope + fun plainFormatter(): Formatters.Plain = + PlainFormatter( + context, + applicationCollector, + permissionsCollector, + deviceCollector, + preferencesCollector + ) + + @Provides + @DataScope + fun markdownFormatter(): Formatters.Markdown = + MarkdownFormatter( + context, + applicationCollector, + permissionsCollector, + deviceCollector, + preferencesCollector + ) + + @Provides + @DataScope + fun jsonFormatter(): Formatters.Json = + JsonFormatter( + context, + applicationCollector, + permissionsCollector, + deviceCollector, + preferencesCollector + ) + + @Provides + @DataScope + fun xmlFormatter(): Formatters.Xml = + XmlFormatter( + context, + applicationCollector, + permissionsCollector, + deviceCollector, + preferencesCollector + ) + + @Provides + @DataScope + fun htmlFormatter(): Formatters.Html = + HtmlFormatter( + context, + applicationCollector, + permissionsCollector, + deviceCollector, + preferencesCollector + ) + //endregion + + //region Memory + abstract val manualTrigger: ManualTrigger + + abstract val foregroundTrigger: ForegroundTrigger + + abstract val shakeTrigger: ShakeTrigger + + abstract val proximityTrigger: ProximityTrigger + + abstract val usbConnectedTrigger: UsbConnectedTrigger + + abstract val airplaneModeOnTrigger: AirplaneModeOnTrigger + + abstract val triggersCache: TriggersCache + + abstract val bundlesCache: BundlesCache + + abstract val preferenceCache: PreferenceCache + + abstract val certificateCache: CertificateCache + + @Provides + @DataScope + fun manualTrigger(): ManualTrigger = + ManualTrigger() + + @Provides + @DataScope + fun shakeTrigger(): ShakeTrigger = + ShakeTrigger(context, this.onTriggered) + + @Provides + @DataScope + fun foregroundTrigger(): ForegroundTrigger = + ForegroundTrigger(this.onTriggered) + + @Provides + @DataScope + fun proximityTrigger(): ProximityTrigger = + ProximityTrigger(context, this.onTriggered) + + @Provides + @DataScope + fun usbConnectedTrigger(): UsbConnectedTrigger = + UsbConnectedTrigger(context, this.onTriggered) + + @Provides + @DataScope + fun airplaneModeOnTrigger(): AirplaneModeOnTrigger = + AirplaneModeOnTrigger(context, this.onTriggered) + + @Provides + @DataScope + fun triggersCache(): TriggersCache = + TriggersCacheFactory( + manualTrigger, + foregroundTrigger, + shakeTrigger, + proximityTrigger, + usbConnectedTrigger, + airplaneModeOnTrigger + ) + + @Provides + @DataScope + fun bundlesCache(): BundlesCache = + InMemoryBundlesCache() + + @Provides + @DataScope + fun preferenceCache(): PreferenceCache = + InMemoryPreferenceCache() + + @Provides + @DataScope + fun certificateCache(): CertificateCache = + InMemoryCertificateCache() + //endregion +} 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 new file mode 100644 index 00000000..e3fb4e66 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/DomainComponent.kt @@ -0,0 +1,370 @@ +package com.infinum.sentinel.di.component + +import android.app.Application +import android.content.Context +import android.content.Intent +import android.text.format.Formatter +import com.google.android.material.snackbar.Snackbar +import com.infinum.sentinel.R +import com.infinum.sentinel.data.models.memory.triggers.TriggerType +import com.infinum.sentinel.data.sources.local.room.dao.BundleMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CertificateMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CrashMonitorDao +import com.infinum.sentinel.data.sources.local.room.dao.CrashesDao +import com.infinum.sentinel.data.sources.local.room.dao.FormatsDao +import com.infinum.sentinel.data.sources.local.room.dao.TriggersDao +import com.infinum.sentinel.data.sources.memory.bundles.BundlesCache +import com.infinum.sentinel.data.sources.memory.certificate.CertificateCache +import com.infinum.sentinel.data.sources.memory.preference.PreferenceCache +import com.infinum.sentinel.data.sources.memory.triggers.TriggersCache +import com.infinum.sentinel.di.scope.DomainScope +import com.infinum.sentinel.domain.Factories +import com.infinum.sentinel.domain.Repositories +import com.infinum.sentinel.domain.bundle.descriptor.BundlesRepository +import com.infinum.sentinel.domain.bundle.descriptor.models.BundleDescriptor +import com.infinum.sentinel.domain.bundle.descriptor.models.BundleParameters +import com.infinum.sentinel.domain.bundle.monitor.BundleMonitorRepository +import com.infinum.sentinel.domain.bundle.monitor.models.BundleMonitorParameters +import com.infinum.sentinel.domain.certificate.CertificateRepository +import com.infinum.sentinel.domain.certificate.monitor.CertificateMonitorRepository +import com.infinum.sentinel.domain.certificate.monitor.models.CertificateMonitorParameters +import com.infinum.sentinel.domain.collectors.CollectorFactory +import com.infinum.sentinel.domain.collectors.Collectors +import com.infinum.sentinel.domain.crash.monitor.CrashMonitorRepository +import com.infinum.sentinel.domain.crash.monitor.models.CrashMonitorParameters +import com.infinum.sentinel.domain.formats.FormatsRepository +import com.infinum.sentinel.domain.formatters.FormatterFactory +import com.infinum.sentinel.domain.formatters.Formatters +import com.infinum.sentinel.domain.preference.PreferenceRepository +import com.infinum.sentinel.domain.triggers.TriggersRepository +import com.infinum.sentinel.domain.triggers.models.TriggerParameters +import com.infinum.sentinel.extensions.enableAirplaneModeOnTrigger +import com.infinum.sentinel.extensions.enableForegroundTrigger +import com.infinum.sentinel.extensions.enableProximityTrigger +import com.infinum.sentinel.extensions.enableShakeTrigger +import com.infinum.sentinel.extensions.enableUsbConnectedTrigger +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.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 +import com.infinum.sentinel.ui.crash.handler.SentinelExceptionHandler +import com.infinum.sentinel.ui.crash.handler.SentinelUncaughtExceptionHandler +import com.infinum.sentinel.ui.shared.Constants +import com.infinum.sentinel.ui.shared.notification.IntentFactory +import com.infinum.sentinel.ui.shared.notification.NotificationFactory +import com.infinum.sentinel.ui.shared.notification.NotificationIntentFactory +import com.infinum.sentinel.ui.shared.notification.SystemNotificationFactory +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides + +@Suppress("TooManyFunctions") +@Component +@DomainScope +internal abstract class DomainComponent( + private val context: Context, + @Component val dataComponent: DataComponent +) { + + private val scope = MainScope() + + abstract val intentFactory: IntentFactory + + abstract val notificationFactory: NotificationFactory + + abstract val sentinelExceptionHandler: SentinelExceptionHandler + + abstract val certificatesObserver: CertificatesObserver + + abstract val sentinelAnrObserver: SentinelAnrObserver + + abstract val sentinelWorkerFactory: SentinelWorkerFactory + + abstract val sentinelWorkManager: SentinelWorkManager + + abstract val sentinelAnrObserverRunnable: SentinelAnrObserverRunnable + + abstract val executorService: ExecutorService + + abstract val collectors: Factories.Collector + + abstract val formatters: Factories.Formatter + + abstract val triggers: Repositories.Triggers + + abstract val formats: Repositories.Formats + + abstract val bundleMonitor: Repositories.BundleMonitor + + abstract val bundles: Repositories.Bundles + + abstract val preferences: Repositories.Preference + + abstract val crashMonitor: Repositories.CrashMonitor + + abstract val certificates: Repositories.Certificate + + abstract val certificateMonitor: Repositories.CertificateMonitor + + fun setup() { + initializeCrashMonitor() + initializeBundleMonitor() + initializeCertificateMonitor() + initializeTriggers() + } + + @Provides + fun executorService(): ExecutorService = + Executors.newSingleThreadExecutor() + + @Provides + fun intentFactory(): IntentFactory = + NotificationIntentFactory(context) + + @Provides + fun notificationFactory(): NotificationFactory = + SystemNotificationFactory(context, intentFactory) + + @Provides + @DomainScope + fun sentinelExceptionHandler( + dao: CrashesDao + ): SentinelExceptionHandler = + SentinelUncaughtExceptionHandler(context, notificationFactory, dao) + + @Provides + @DomainScope + fun certificatesObserver( + collectors: Factories.Collector, + ): CertificatesObserver = + CertificatesObserver(context, collectors, notificationFactory) + + @Provides + @DomainScope + 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) + + @Provides + @DomainScope + fun sentinelAnrObserver(): SentinelAnrObserver = + SentinelUiAnrObserver(sentinelAnrObserverRunnable, executorService) + + @Provides + @DomainScope + fun formatters( + plain: Formatters.Plain, + markdown: Formatters.Markdown, + json: Formatters.Json, + xml: Formatters.Xml, + html: Formatters.Html + ): Factories.Formatter = + FormatterFactory(plain, markdown, json, xml, html) + + @Suppress("LongParameterList") + @Provides + @DomainScope + fun collectors( + device: Collectors.Device, + application: Collectors.Application, + permissions: Collectors.Permissions, + preferences: Collectors.Preferences, + certificates: Collectors.Certificates, + tools: Collectors.Tools + ): Factories.Collector = + CollectorFactory(device, application, permissions, preferences, certificates, tools) + + @Provides + @DomainScope + fun triggers(dao: TriggersDao, cache: TriggersCache): Repositories.Triggers = + TriggersRepository(dao, cache) + + @Provides + @DomainScope + fun formats(dao: FormatsDao): Repositories.Formats = + FormatsRepository(dao) + + @Provides + @DomainScope + fun bundleMonitor(dao: BundleMonitorDao): Repositories.BundleMonitor = + BundleMonitorRepository(dao) + + @Provides + @DomainScope + fun bundles(cache: BundlesCache): Repositories.Bundles = + BundlesRepository(cache) + + @Provides + @DomainScope + fun preferences(cache: PreferenceCache): Repositories.Preference = + PreferenceRepository(context, cache) + + @Provides + @DomainScope + fun crashMonitor(dao: CrashMonitorDao): Repositories.CrashMonitor = + CrashMonitorRepository(dao) + + @Provides + @DomainScope + fun certificates(cache: CertificateCache): Repositories.Certificate = + CertificateRepository(cache) + + @Provides + @DomainScope + fun certificateMonitor(dao: CertificateMonitorDao): Repositories.CertificateMonitor = + CertificateMonitorRepository(dao) + + private fun initializeCrashMonitor() { + Thread.setDefaultUncaughtExceptionHandler(sentinelExceptionHandler as Thread.UncaughtExceptionHandler) + scope.launch { + withContext(Dispatchers.IO) { + val entity = crashMonitor.load(CrashMonitorParameters()).first() + if (entity.notifyExceptions) { + sentinelExceptionHandler.start() + } else { + sentinelExceptionHandler.stop() + } + if (entity.notifyExceptions) { + sentinelAnrObserver.start() + } else { + sentinelAnrObserver.stop() + } + } + } + } + + private fun initializeCertificateMonitor() { + scope.launch { + withContext(Dispatchers.IO) { + val monitorEntity = certificateMonitor.load(CertificateMonitorParameters()).first() + monitorEntity.takeIf { it.runOnStart }?.let { + certificatesObserver.activate(it) + } ?: certificatesObserver.deactivate() + monitorEntity.takeIf { it.runInBackground }?.let { + sentinelWorkManager.startCertificatesCheck(it) + } ?: sentinelWorkManager.stopCertificatesCheck() + } + } + } + + private fun initializeBundleMonitor() { + val notificationCallbacks = BundleMonitorNotificationCallbacks() + + (this.context as? Application)?.registerActivityLifecycleCallbacks(notificationCallbacks) + (this.context as? Application) + ?.registerActivityLifecycleCallbacks( + BundleMonitorActivityCallbacks { activity, timestamp, className, callSite, bundle -> + scope.launch { + withContext(Dispatchers.IO) { + val sizeTree = bundle.sizeTree() + bundles.save( + BundleParameters( + descriptor = BundleDescriptor( + timestamp = timestamp, + className = className, + callSite = callSite, + bundleTree = sizeTree + ) + ) + ) + + val currentMonitor = + bundleMonitor.load(BundleMonitorParameters()).first() + if (currentMonitor.notify && sizeTree.size > + currentMonitor.limit * Constants.BYTE_MULTIPLIER + ) { + notificationCallbacks.currentActivity?.let { + Snackbar.make( + it.window.decorView, + buildString { + append(className) + append(System.lineSeparator()) + append( + Formatter.formatFileSize( + activity, + sizeTree.size.toLong() + ) + ) + }, + Snackbar.LENGTH_LONG + ) + .setAction(R.string.sentinel_show) { view -> + view.context.startActivity( + Intent(activity, BundleDetailsActivity::class.java) + .apply { + putExtra( + Constants.Keys.BUNDLE_ID, + sizeTree.id + ) + } + ) + } + .show() + } + } + } + } + } + ) + } + + private fun initializeTriggers() { + scope.launch { + withContext(Dispatchers.IO) { + triggers.load(TriggerParameters()).first() + .forEach { entity -> + when (entity.type) { + TriggerType.SHAKE -> + context.enableShakeTrigger()?.let { + entity.enabled = it + } + TriggerType.FOREGROUND -> + context.enableForegroundTrigger()?.let { + entity.enabled = it + } + TriggerType.PROXIMITY -> + context.enableProximityTrigger()?.let { + entity.enabled = it + } + TriggerType.USB_CONNECTED -> + context.enableUsbConnectedTrigger()?.let { + entity.enabled = it + } + TriggerType.AIRPLANE_MODE_ON -> + context.enableAirplaneModeOnTrigger()?.let { + entity.enabled = it + } + else -> null + }?.let { + triggers.save( + TriggerParameters( + entity = entity + ) + ) + } + } + } + } + } +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/PresentationComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/PresentationComponent.kt new file mode 100644 index 00000000..276f7226 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/PresentationComponent.kt @@ -0,0 +1,43 @@ +package com.infinum.sentinel.di.component + +import android.content.Context +import android.content.Intent +import com.infinum.sentinel.Sentinel +import com.infinum.sentinel.di.scope.PresentationScope +import com.infinum.sentinel.ui.main.SentinelActivity +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides + +@Component +@PresentationScope +internal abstract class PresentationComponent( + @get:Provides val context: Context, + @Component val viewModelComponent: ViewModelComponent +) { + + abstract val launchIntent: Intent + + @Provides + @PresentationScope + fun launchIntent(): Intent = + Intent(context, SentinelActivity::class.java) + .apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) + } + + fun show() = + context.startActivity(launchIntent) + + fun setExceptionHandler(handler: Thread.UncaughtExceptionHandler?) = + viewModelComponent + .domainComponent + .sentinelExceptionHandler + .setExceptionHandler(handler) + + fun setAnrListener(listener: Sentinel.ApplicationNotRespondingListener?) = + viewModelComponent + .domainComponent + .sentinelAnrObserver + .setListener(listener) +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/ViewModelComponent.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/ViewModelComponent.kt new file mode 100644 index 00000000..1b03a155 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/component/ViewModelComponent.kt @@ -0,0 +1,127 @@ +package com.infinum.sentinel.di.component + +import androidx.lifecycle.ViewModel +import com.infinum.sentinel.ui.bundles.BundlesViewModel +import com.infinum.sentinel.ui.bundles.details.BundleDetailsViewModel +import com.infinum.sentinel.ui.certificates.CertificatesViewModel +import com.infinum.sentinel.ui.certificates.details.CertificateDetailsViewModel +import com.infinum.sentinel.ui.crash.CrashesViewModel +import com.infinum.sentinel.ui.crash.details.CrashDetailsViewModel +import com.infinum.sentinel.ui.main.SentinelViewModel +import com.infinum.sentinel.ui.main.application.ApplicationViewModel +import com.infinum.sentinel.ui.main.device.DeviceViewModel +import com.infinum.sentinel.ui.main.permissions.PermissionsViewModel +import com.infinum.sentinel.ui.main.preferences.PreferencesViewModel +import com.infinum.sentinel.ui.main.preferences.editor.PreferenceEditorViewModel +import com.infinum.sentinel.ui.main.tools.ToolsViewModel +import com.infinum.sentinel.ui.settings.SettingsViewModel +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.IntoMap +import me.tatarka.inject.annotations.Provides + +@Suppress("TooManyFunctions") +@Component +internal abstract class ViewModelComponent( + @Component val domainComponent: DomainComponent +) { + + abstract val viewModelMap: Map, ViewModel> + + abstract val sentinel: SentinelViewModel + + abstract val device: DeviceViewModel + + abstract val application: ApplicationViewModel + + abstract val permissions: PermissionsViewModel + + abstract val preferences: PreferencesViewModel + + abstract val preferenceEditor: PreferenceEditorViewModel + + abstract val tools: ToolsViewModel + + abstract val settings: SettingsViewModel + + abstract val bundles: BundlesViewModel + + abstract val bundleDetails: BundleDetailsViewModel + + abstract val crashes: CrashesViewModel + + abstract val crashDetails: CrashDetailsViewModel + + abstract val certificates: CertificatesViewModel + + abstract val certificateDetails: CertificateDetailsViewModel + + @IntoMap + @Provides + fun sentinel(): Pair, ViewModel> = + SentinelViewModel::class.java to sentinel + + @IntoMap + @Provides + fun device(): Pair, ViewModel> = + DeviceViewModel::class.java to device + + @IntoMap + @Provides + fun application(): Pair, ViewModel> = + ApplicationViewModel::class.java to application + + @IntoMap + @Provides + fun permissions(): Pair, ViewModel> = + PermissionsViewModel::class.java to permissions + + @IntoMap + @Provides + fun preferences(): Pair, ViewModel> = + PreferencesViewModel::class.java to preferences + + @IntoMap + @Provides + fun preferenceEditor(): Pair, ViewModel> = + PreferenceEditorViewModel::class.java to preferenceEditor + + @IntoMap + @Provides + fun tools(): Pair, ViewModel> = + ToolsViewModel::class.java to tools + + @IntoMap + @Provides + fun settings(): Pair, ViewModel> = + SettingsViewModel::class.java to settings + + @IntoMap + @Provides + fun bundles(): Pair, ViewModel> = + BundlesViewModel::class.java to bundles + + @IntoMap + @Provides + fun bundleDetails(): Pair, ViewModel> = + BundleDetailsViewModel::class.java to bundleDetails + + @IntoMap + @Provides + fun crashes(): Pair, ViewModel> = + CrashesViewModel::class.java to crashes + + @IntoMap + @Provides + fun crashDetails(): Pair, ViewModel> = + CrashDetailsViewModel::class.java to crashDetails + + @IntoMap + @Provides + fun certificates(): Pair, ViewModel> = + CertificatesViewModel::class.java to certificates + + @IntoMap + @Provides + fun certificateDetails(): Pair, ViewModel> = + CertificateDetailsViewModel::class.java to certificateDetails +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DataScope.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DataScope.kt new file mode 100644 index 00000000..3bfe246d --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DataScope.kt @@ -0,0 +1,6 @@ +package com.infinum.sentinel.di.scope + +import me.tatarka.inject.annotations.Scope + +@Scope +internal annotation class DataScope diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DomainScope.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DomainScope.kt new file mode 100644 index 00000000..88a60e6a --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/DomainScope.kt @@ -0,0 +1,6 @@ +package com.infinum.sentinel.di.scope + +import me.tatarka.inject.annotations.Scope + +@Scope +internal annotation class DomainScope diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/PresentationScope.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/PresentationScope.kt new file mode 100644 index 00000000..a6c33fd0 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/di/scope/PresentationScope.kt @@ -0,0 +1,6 @@ +package com.infinum.sentinel.di.scope + +import me.tatarka.inject.annotations.Scope + +@Scope +internal annotation class PresentationScope diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/Domain.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/Domain.kt deleted file mode 100644 index 4dd757ca..00000000 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/Domain.kt +++ /dev/null @@ -1,100 +0,0 @@ -package com.infinum.sentinel.domain - -import com.infinum.sentinel.Sentinel -import com.infinum.sentinel.data.Data -import com.infinum.sentinel.domain.bundle.descriptor.BundlesRepository -import com.infinum.sentinel.domain.bundle.monitor.BundleMonitorRepository -import com.infinum.sentinel.domain.certificate.CertificateRepository -import com.infinum.sentinel.domain.certificate.monitor.CertificateMonitorRepository -import com.infinum.sentinel.domain.collectors.CollectorFactory -import com.infinum.sentinel.domain.crash.monitor.CrashMonitorRepository -import com.infinum.sentinel.domain.formats.FormatsRepository -import com.infinum.sentinel.domain.formatters.FormatterFactory -import com.infinum.sentinel.domain.preference.PreferenceRepository -import com.infinum.sentinel.domain.triggers.TriggersRepository -import java.security.cert.X509Certificate -import org.koin.core.module.Module -import org.koin.core.parameter.parametersOf -import org.koin.dsl.module - -@Suppress("TooManyFunctions") -internal object Domain { - - private var tools: Set = setOf() - private var userCertificates: List = listOf() - - fun setup( - tools: Set, - userManagers: List, - onTriggered: () -> Unit - ) { - this.tools = tools - this.userCertificates = userManagers - Data.setup(onTriggered) - } - - fun modules(): List = - Data.modules().plus( - listOf( - collectors(), - formatters(), - triggers(), - formats(), - bundleMonitor(), - bundles(), - preferences(), - crashMonitor(), - certificates(), - certificateMonitor() - ) - ) - - private fun collectors() = module { - single { - CollectorFactory( - get(), - get(), - get(), - get(), - get { parametersOf(userCertificates) }, - get { parametersOf(tools) } - ) - } - } - - private fun formatters() = module { - single { FormatterFactory(get(), get(), get(), get(), get()) } - } - - private fun triggers() = module { - single { TriggersRepository(get(), get()) } - } - - private fun formats() = module { - single { FormatsRepository(get()) } - } - - private fun bundleMonitor() = module { - single { BundleMonitorRepository(get()) } - } - - private fun bundles() = module { - single { BundlesRepository(get()) } - } - - private fun preferences() = module { - single { PreferenceRepository(get(), get()) } - } - - private fun crashMonitor() = module { - single { CrashMonitorRepository(get()) } - } - - private fun certificates() = module { - single { CertificateRepository(get()) } - } - - private fun certificateMonitor() = module { - single { CertificateMonitorRepository(get()) } - } -} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/descriptor/BundlesRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/descriptor/BundlesRepository.kt index bb83865a..e797a55c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/descriptor/BundlesRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/descriptor/BundlesRepository.kt @@ -5,7 +5,9 @@ import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.bundle.descriptor.models.BundleDescriptor import com.infinum.sentinel.domain.bundle.descriptor.models.BundleParameters import kotlinx.coroutines.flow.Flow +import me.tatarka.inject.annotations.Inject +@Inject internal class BundlesRepository( private val cache: BundlesCache ) : Repositories.Bundles { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/monitor/BundleMonitorRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/monitor/BundleMonitorRepository.kt index fc73773e..19e11de3 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/monitor/BundleMonitorRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/bundle/monitor/BundleMonitorRepository.kt @@ -5,7 +5,9 @@ import com.infinum.sentinel.data.sources.local.room.dao.BundleMonitorDao import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.bundle.monitor.models.BundleMonitorParameters import kotlinx.coroutines.flow.Flow +import me.tatarka.inject.annotations.Inject +@Inject internal class BundleMonitorRepository( private val dao: BundleMonitorDao ) : Repositories.BundleMonitor { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/CertificateRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/CertificateRepository.kt index 5f34e87b..e8bce928 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/CertificateRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/CertificateRepository.kt @@ -4,7 +4,9 @@ import com.infinum.sentinel.data.models.raw.CertificateData import com.infinum.sentinel.data.sources.memory.certificate.CertificateCache import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.certificate.models.CertificateParameters +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificateRepository( private val memoryCache: CertificateCache ) : Repositories.Certificate { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/monitor/CertificateMonitorRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/monitor/CertificateMonitorRepository.kt index adfc6e1b..7af4a8c3 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/monitor/CertificateMonitorRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/certificate/monitor/CertificateMonitorRepository.kt @@ -5,7 +5,9 @@ import com.infinum.sentinel.data.sources.local.room.dao.CertificateMonitorDao import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.certificate.monitor.models.CertificateMonitorParameters import kotlinx.coroutines.flow.Flow +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificateMonitorRepository( private val dao: CertificateMonitorDao ) : Repositories.CertificateMonitor { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/crash/monitor/CrashMonitorRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/crash/monitor/CrashMonitorRepository.kt index 6d164741..2c678e90 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/crash/monitor/CrashMonitorRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/crash/monitor/CrashMonitorRepository.kt @@ -5,7 +5,9 @@ import com.infinum.sentinel.data.sources.local.room.dao.CrashMonitorDao import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.crash.monitor.models.CrashMonitorParameters import kotlinx.coroutines.flow.Flow +import me.tatarka.inject.annotations.Inject +@Inject internal class CrashMonitorRepository( private val dao: CrashMonitorDao ) : Repositories.CrashMonitor { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/formats/FormatsRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/formats/FormatsRepository.kt index d9b0d00f..c1e6d4f5 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/formats/FormatsRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/formats/FormatsRepository.kt @@ -5,7 +5,9 @@ import com.infinum.sentinel.data.sources.local.room.dao.FormatsDao import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.formats.models.FormatsParameters import kotlinx.coroutines.flow.Flow +import me.tatarka.inject.annotations.Inject +@Inject internal class FormatsRepository( private val dao: FormatsDao ) : Repositories.Formats { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/preference/PreferenceRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/preference/PreferenceRepository.kt index f43d23c6..b3292e12 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/preference/PreferenceRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/preference/PreferenceRepository.kt @@ -8,7 +8,9 @@ import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.preference.models.PreferenceParameters import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +import me.tatarka.inject.annotations.Inject +@Inject internal class PreferenceRepository( private val context: Context, private val memoryCache: PreferenceCache diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/triggers/TriggersRepository.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/triggers/TriggersRepository.kt index 723646e1..3e96d69f 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/domain/triggers/TriggersRepository.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/domain/triggers/TriggersRepository.kt @@ -8,7 +8,9 @@ import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.triggers.models.TriggerParameters import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onEach +import me.tatarka.inject.annotations.Inject +@Inject internal class TriggersRepository( private val dao: TriggersDao, private val cache: TriggersCache diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Bundle.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Bundle.kt index e3812a3b..ec417dad 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Bundle.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Bundle.kt @@ -18,21 +18,27 @@ internal fun Bundle.sizeTree(): BundleTree { return BundleTree( "${System.identityHashCode(this)}", originalSize, - original.keySet().map { key -> - val withoutKey = Bundle(original) - - val internalTree: BundleTree? = withoutKey.getBundle(key)?.sizeTree() - - withoutKey.remove(key) - - val valueSize = originalSize - withoutKey.sizeAsParcelable - - BundleTree( - key, - valueSize, - internalTree?.let { listOf(it) } ?: emptyList() - ) - } + original + .keySet() + .filter { + @Suppress("DEPRECATION") + original.get(it) is Bundle + } + .map { key -> + val withoutKey = Bundle(original) + + val internalTree: BundleTree? = withoutKey.getBundle(key)?.sizeTree() + + withoutKey.remove(key) + + val valueSize = originalSize - withoutKey.sizeAsParcelable + + BundleTree( + key, + valueSize, + internalTree?.let { listOf(it) } ?: emptyList() + ) + } ) } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Context.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Context.kt index da5d8373..a2e6e12c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Context.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/Context.kt @@ -3,6 +3,7 @@ package com.infinum.sentinel.extensions import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.os.Build import android.util.DisplayMetrics @@ -13,6 +14,21 @@ import java.math.RoundingMode import kotlin.math.pow import kotlin.math.sqrt +private const val KEY_TRIGGER_SHAKE: String = + "com.infinum.sentinel.trigger.shake" + +private const val KEY_TRIGGER_PROXIMITY: String = + "com.infinum.sentinel.trigger.proximity" + +private const val KEY_TRIGGER_FOREGROUND: String = + "com.infinum.sentinel.trigger.foreground" + +private const val KEY_TRIGGER_USB_CONNECTED: String = + "com.infinum.sentinel.trigger.usb_connected" + +private const val KEY_TRIGGER_AIRPLANE_MODE_ON: String = + "com.infinum.sentinel.trigger.airplane_mode_on" + internal fun Context.isPermissionGranted(name: String): Boolean = packageManager.checkPermission(name, packageName) == PackageManager.PERMISSION_GRANTED @@ -35,23 +51,52 @@ internal fun Context.copyToClipboard(key: String, value: String): Boolean = false } -internal val Context.applicationName: String - get() = ( - 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 - ) +@Suppress("DEPRECATION") +private val Context.info: ApplicationInfo + get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager + .getApplicationInfo( + packageName, + PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()) + ) + } else { + packageManager + .getApplicationInfo( + packageName, + PackageManager.GET_META_DATA + ) + } + +private fun Context.enableTrigger(key: String): Boolean? = + info.metaData + ?.getInt(key, -1) + ?.takeIf { it != -1 } + ?.let { + when (it) { + 1 -> true + 0 -> false + else -> null } - ) as? String - ) ?: getString(R.string.sentinel_name) + } + +internal fun Context.enableShakeTrigger(): Boolean? = + enableTrigger(KEY_TRIGGER_SHAKE) + +internal fun Context.enableProximityTrigger(): Boolean? = + enableTrigger(KEY_TRIGGER_PROXIMITY) + +internal fun Context.enableForegroundTrigger(): Boolean? = + enableTrigger(KEY_TRIGGER_FOREGROUND) + +internal fun Context.enableUsbConnectedTrigger(): Boolean? = + enableTrigger(KEY_TRIGGER_USB_CONNECTED) + +internal fun Context.enableAirplaneModeOnTrigger(): Boolean? = + enableTrigger(KEY_TRIGGER_AIRPLANE_MODE_ON) + +internal val Context.applicationName: String + get() = (packageManager.getApplicationLabel(this.info) as? String) + ?: getString(R.string.sentinel_name) @Suppress("DEPRECATION") internal val Context.widthPixels: Int diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/IntentBuilder.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/IntentBuilder.kt index 68e01a03..69095b52 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/IntentBuilder.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/IntentBuilder.kt @@ -2,10 +2,10 @@ package com.infinum.sentinel.extensions import androidx.core.app.ShareCompat import com.infinum.sentinel.R -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.ui.shared.Constants internal fun ShareCompat.IntentBuilder.shareText(text: String) = this.setChooserTitle(R.string.sentinel_name) - .setType(Presentation.Constants.SHARE_MIME_TYPE) + .setType(Constants.SHARE_MIME_TYPE) .setText(text) .startChooser() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/ViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/ViewModel.kt new file mode 100644 index 00000000..9728ba6c --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/extensions/ViewModel.kt @@ -0,0 +1,65 @@ +package com.infinum.sentinel.extensions + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.AbstractSavedStateViewModelFactory +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.savedstate.SavedStateRegistryOwner +import com.infinum.sentinel.di.LibraryComponents + +internal inline fun ComponentActivity.viewModels(): Lazy = + viewModels { InjectedViewModelFactory } + +internal inline fun ComponentActivity.viewModels( + state: SavedStateHandle +): Lazy = + viewModels { + InjectedSavedStateViewModelFactory(this, intent.extras, state) + } + +internal inline fun Fragment.viewModels(): Lazy = + viewModels { InjectedViewModelFactory } + +internal inline fun Fragment.viewModels( + state: SavedStateHandle +): Lazy = + viewModels { + InjectedSavedStateViewModelFactory(this, arguments, state) + } + +@Suppress("UNCHECKED_CAST") +internal object InjectedViewModelFactory : ViewModelProvider.Factory { + + override fun create(modelClass: Class): T = + LibraryComponents.viewModels().viewModelMap[modelClass] as T +} + +@Suppress("UNCHECKED_CAST") +internal class InjectedSavedStateViewModelFactory( + owner: SavedStateRegistryOwner, + defaultArguments: Bundle?, + private val state: SavedStateHandle +) : AbstractSavedStateViewModelFactory(owner, defaultArguments) { + + override fun create(key: String, modelClass: Class, handle: SavedStateHandle): T { + return if (modelClass.constructors.any { it.parameterTypes.contains(SavedStateHandle::class.java) }) { + (LibraryComponents.viewModels().viewModelMap[modelClass] as T).let { clazz -> + clazz.javaClass.constructors + .find { it.parameterTypes.contains(SavedStateHandle::class.java) } + ?.parameterTypes?.find { it == SavedStateHandle::class.java } + ?.let { param -> + val field = clazz.javaClass.getDeclaredField(param.name) + field.set(clazz, state) + } + clazz + } + } else { + LibraryComponents.viewModels().viewModelMap[modelClass] as T + } + } +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/Presentation.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/Presentation.kt deleted file mode 100644 index f4938442..00000000 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/Presentation.kt +++ /dev/null @@ -1,263 +0,0 @@ -package com.infinum.sentinel.ui - -import android.annotation.SuppressLint -import android.app.Application -import android.content.Context -import android.content.Intent -import android.text.format.Formatter -import com.google.android.material.snackbar.Snackbar -import com.infinum.sentinel.R -import com.infinum.sentinel.Sentinel -import com.infinum.sentinel.di.LibraryKoin -import com.infinum.sentinel.domain.Domain -import com.infinum.sentinel.domain.Repositories -import com.infinum.sentinel.domain.bundle.descriptor.models.BundleDescriptor -import com.infinum.sentinel.domain.bundle.descriptor.models.BundleParameters -import com.infinum.sentinel.domain.bundle.monitor.models.BundleMonitorParameters -import com.infinum.sentinel.domain.certificate.monitor.models.CertificateMonitorParameters -import com.infinum.sentinel.domain.crash.monitor.models.CrashMonitorParameters -import com.infinum.sentinel.domain.triggers.models.TriggerParameters -import com.infinum.sentinel.extensions.sizeTree -import com.infinum.sentinel.ui.Presentation.Constants.BYTE_MULTIPLIER -import com.infinum.sentinel.ui.bundles.BundlesViewModel -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.bundles.details.BundleDetailsViewModel -import com.infinum.sentinel.ui.certificates.CertificatesViewModel -import com.infinum.sentinel.ui.certificates.details.CertificateDetailsViewModel -import com.infinum.sentinel.ui.certificates.observer.CertificatesObserver -import com.infinum.sentinel.ui.certificates.observer.SentinelWorkManager -import com.infinum.sentinel.ui.crash.CrashesViewModel -import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserver -import com.infinum.sentinel.ui.crash.anr.SentinelAnrObserverRunnable -import com.infinum.sentinel.ui.crash.anr.SentinelUiAnrObserver -import com.infinum.sentinel.ui.crash.details.CrashDetailsViewModel -import com.infinum.sentinel.ui.crash.handler.SentinelExceptionHandler -import com.infinum.sentinel.ui.crash.handler.SentinelUncaughtExceptionHandler -import com.infinum.sentinel.ui.main.SentinelActivity -import com.infinum.sentinel.ui.main.SentinelViewModel -import com.infinum.sentinel.ui.main.application.ApplicationViewModel -import com.infinum.sentinel.ui.main.device.DeviceViewModel -import com.infinum.sentinel.ui.main.permissions.PermissionsViewModel -import com.infinum.sentinel.ui.main.preferences.PreferencesViewModel -import com.infinum.sentinel.ui.main.preferences.editor.PreferenceEditorViewModel -import com.infinum.sentinel.ui.main.tools.ToolsViewModel -import com.infinum.sentinel.ui.settings.SettingsViewModel -import com.infinum.sentinel.ui.shared.notification.IntentFactory -import com.infinum.sentinel.ui.shared.notification.NotificationFactory -import com.infinum.sentinel.ui.shared.notification.NotificationIntentFactory -import com.infinum.sentinel.ui.shared.notification.SystemNotificationFactory -import com.infinum.sentinel.ui.tools.AppInfoTool -import com.infinum.sentinel.ui.tools.BundleMonitorTool -import com.infinum.sentinel.ui.tools.CertificateTool -import com.infinum.sentinel.ui.tools.CrashMonitorTool -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch -import org.koin.androidx.viewmodel.dsl.viewModel -import org.koin.core.module.Module -import org.koin.dsl.module - -@SuppressLint("StaticFieldLeak") -@Suppress("TooManyFunctions") -internal object Presentation { - - object Constants { - const val BYTE_MULTIPLIER = 1000 - const val SHARE_MIME_TYPE = "text/plain" - const val NOTIFICATIONS_CHANNEL_ID = "sentinel" - - object Keys { - const val BUNDLE_ID = "KEY_BUNDLE_ID" - const val SHOULD_REFRESH: String = "KEY_SHOULD_REFRESH" - const val APPLICATION_NAME: String = "KEY_APPLICATION_NAME" - const val CRASH_ID: String = "KEY_CRASH_ID" - const val NOTIFY_INVALID_NOW: String = "KEY_NOTIFY_INVALID_NOW" - 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" - } - } - - private val DEFAULT_TOOLS = setOf( - CrashMonitorTool(), - BundleMonitorTool(), - AppInfoTool() - ) - - private lateinit var context: Context - - private val scope = MainScope() - - fun initialize(context: Context) { - this.context = context - - initializeCrashMonitor() - initializeBundleMonitor() - } - - fun setExceptionHandler(handler: Thread.UncaughtExceptionHandler?) { - val exceptionHandler = LibraryKoin.koin().get() - exceptionHandler.setExceptionHandler(handler) - } - - fun setAnrListener(listener: Sentinel.ApplicationNotRespondingListener?) { - val observer = LibraryKoin.koin().get() - observer.setListener(listener) - } - - fun setup(tools: Set, onTriggered: () -> Unit) { - Domain.setup( - tools.plus(DEFAULT_TOOLS), - tools.filterIsInstance().firstOrNull()?.userCertificates.orEmpty(), - onTriggered - ) - initializeTriggers() - initializeCertificateMonitor() - } - - fun show() = - if (this::context.isInitialized) { - context.startActivity( - Intent(context, SentinelActivity::class.java) - .apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - } - ) - } else { - throw NullPointerException("Presentation context has not been initialized.") - } - - fun modules(): List = - Domain.modules().plus( - listOf( - viewModels(), - factories() - ) - ) - - private fun initializeCrashMonitor() { - val exceptionHandler = LibraryKoin.koin().get() - Thread.setDefaultUncaughtExceptionHandler(exceptionHandler as Thread.UncaughtExceptionHandler) - val anrObserver = LibraryKoin.koin().get() - - val crashMonitor = LibraryKoin.koin().get() - scope.launch { - val entity = crashMonitor.load(CrashMonitorParameters()).first() - if (entity.notifyExceptions) { - exceptionHandler.start() - } else { - exceptionHandler.stop() - } - if (entity.notifyExceptions) { - anrObserver.start() - } else { - anrObserver.stop() - } - } - } - - private fun initializeBundleMonitor() { - val bundleMonitor = LibraryKoin.koin().get() - val bundles = LibraryKoin.koin().get() - val notificationCallbacks = BundleMonitorNotificationCallbacks() - - (this.context.applicationContext as? Application)?.registerActivityLifecycleCallbacks(notificationCallbacks) - (this.context.applicationContext as? Application) - ?.registerActivityLifecycleCallbacks( - BundleMonitorActivityCallbacks { activity, timestamp, className, callSite, bundle -> - scope.launch { - val sizeTree = bundle.sizeTree() - bundles.save( - BundleParameters( - descriptor = BundleDescriptor( - timestamp = timestamp, - className = className, - callSite = callSite, - bundleTree = sizeTree - ) - ) - ) - - val currentMonitor = bundleMonitor.load(BundleMonitorParameters()).first() - if (currentMonitor.notify && sizeTree.size > currentMonitor.limit * BYTE_MULTIPLIER) { - notificationCallbacks.currentActivity?.let { - Snackbar.make( - it.window.decorView, - "$className${System.lineSeparator()}" + - Formatter.formatFileSize(activity, sizeTree.size.toLong()), - Snackbar.LENGTH_LONG - ) - .setAction(R.string.sentinel_show) { view -> - view.context.startActivity( - Intent(activity, BundleDetailsActivity::class.java) - .apply { - putExtra(Constants.Keys.BUNDLE_ID, sizeTree.id) - } - ) - } - .show() - } - } - } - } - ) - } - - private fun initializeTriggers() { - val triggers = LibraryKoin.koin().get() - scope.launch { - triggers.load(TriggerParameters()).first() - } - } - - private fun initializeCertificateMonitor() { - val certificateMonitor = LibraryKoin.koin().get() - val certificatesObserver = LibraryKoin.koin().get() - val workManager = LibraryKoin.koin().get() - scope.launch { - val monitorEntity = certificateMonitor.load(CertificateMonitorParameters()).first() - monitorEntity.takeIf { it.runOnStart }?.let { - certificatesObserver.activate(it) - } ?: certificatesObserver.deactivate() - monitorEntity.takeIf { it.runInBackground }?.let { - workManager.startCertificatesCheck(it) - } ?: workManager.stopCertificatesCheck() - } - } - - private fun viewModels() = module { - viewModel { SentinelViewModel(get(), get(), get(), get()) } - viewModel { DeviceViewModel(get()) } - viewModel { ApplicationViewModel(get()) } - viewModel { PermissionsViewModel(get()) } - viewModel { PreferencesViewModel(get(), get()) } - viewModel { PreferenceEditorViewModel(get()) } - viewModel { ToolsViewModel(get()) } - viewModel { SettingsViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) } - viewModel { BundlesViewModel(get(), get()) } - viewModel { BundleDetailsViewModel(get()) } - viewModel { CrashesViewModel(get()) } - viewModel { CrashDetailsViewModel(get(), get(), get(), get()) } - viewModel { CertificatesViewModel(get(), get(), get()) } - viewModel { CertificateDetailsViewModel(get(), get()) } - } - - private fun factories() = module { - factory { NotificationIntentFactory(get()) } - factory { SystemNotificationFactory(get(), get()) } - - single { SentinelUncaughtExceptionHandler(get(), get(), get()) } - - single { SentinelAnrObserverRunnable(get(), get(), get()) } - factory { Executors.newSingleThreadExecutor() } - single { SentinelUiAnrObserver(get(), get()) } - - single { CertificatesObserver(get(), get(), get()) } - single { SentinelWorkManager(get()) } - } -} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesFragment.kt index be0686cc..60246ecb 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesFragment.kt @@ -12,12 +12,12 @@ import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentBundlesBinding import com.infinum.sentinel.extensions.searchView import com.infinum.sentinel.extensions.setup -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.bundles.details.BundleDetailsActivity +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import com.infinum.sentinel.ui.shared.edgefactories.bounce.BounceEdgeEffectFactory -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class BundlesFragment : BaseChildFragment(R.layout.sentinel_fragment_bundles) { @@ -31,7 +31,7 @@ internal class BundlesFragment : BaseChildFragment(R.layo SentinelFragmentBundlesBinding::bind ) - override val viewModel: BundlesViewModel by viewModel() + override val viewModel: BundlesViewModel by viewModels() private val adapter = BundlesAdapter( onListChanged = { isEmpty -> @@ -41,7 +41,7 @@ internal class BundlesFragment : BaseChildFragment(R.layo startActivity( Intent(requireContext(), BundleDetailsActivity::class.java) .apply { - putExtra(Presentation.Constants.Keys.BUNDLE_ID, it.bundleTree.id) + putExtra(Constants.Keys.BUNDLE_ID, it.bundleTree.id) } ) } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesViewModel.kt index bb723252..75906209 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/BundlesViewModel.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import me.tatarka.inject.annotations.Inject +@Inject internal class BundlesViewModel( private val bundleMonitor: Repositories.BundleMonitor, private val bundles: Repositories.Bundles diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/callbacks/BundleMonitorActivityCallbacks.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/callbacks/BundleMonitorActivityCallbacks.kt index fa65e517..ebe3dc8b 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/callbacks/BundleMonitorActivityCallbacks.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/callbacks/BundleMonitorActivityCallbacks.kt @@ -14,7 +14,10 @@ internal class BundleMonitorActivityCallbacks( override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { if (activity is FragmentActivity) { - activity.supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentCallbacks, true) + activity.supportFragmentManager.registerFragmentLifecycleCallbacks( + fragmentCallbacks, + true + ) } if (activity.isMonitoredScreen) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsActivity.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsActivity.kt index 15136506..6bfe9818 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsActivity.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsActivity.kt @@ -2,7 +2,7 @@ package com.infinum.sentinel.ui.bundles.details import android.os.Bundle import androidx.annotation.RestrictTo -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildActivity @RestrictTo(RestrictTo.Scope.LIBRARY) @@ -14,7 +14,7 @@ internal class BundleDetailsActivity : BaseChildActivity() { supportFragmentManager.beginTransaction() .replace( android.R.id.content, - BundleDetailsFragment.newInstance(intent.extras?.getString(Presentation.Constants.Keys.BUNDLE_ID)), + BundleDetailsFragment.newInstance(intent.extras?.getString(Constants.Keys.BUNDLE_ID)), BundleDetailsFragment.TAG ) .commit() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsFragment.kt index 4fbd80e7..b469e49a 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsFragment.kt @@ -8,11 +8,11 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentBundleDetailsBinding -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.extensions.viewModels +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import com.infinum.sentinel.ui.shared.edgefactories.bounce.BounceEdgeEffectFactory -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class BundleDetailsFragment : @@ -21,7 +21,7 @@ internal class BundleDetailsFragment : companion object { fun newInstance(bundleId: String?) = BundleDetailsFragment().apply { arguments = Bundle().apply { - putString(Presentation.Constants.Keys.BUNDLE_ID, bundleId) + putString(Constants.Keys.BUNDLE_ID, bundleId) } } @@ -32,7 +32,7 @@ internal class BundleDetailsFragment : SentinelFragmentBundleDetailsBinding::bind ) - override val viewModel: BundleDetailsViewModel by viewModel() + override val viewModel: BundleDetailsViewModel by viewModels() private var bundleId: String? = null @@ -41,7 +41,7 @@ internal class BundleDetailsFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - bundleId = arguments?.getString(Presentation.Constants.Keys.BUNDLE_ID) + bundleId = arguments?.getString(Constants.Keys.BUNDLE_ID) viewModel.setBundleId(bundleId) } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsViewModel.kt index 400b9c5e..a57e5418 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/bundles/details/BundleDetailsViewModel.kt @@ -8,7 +8,9 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import me.tatarka.inject.annotations.Inject +@Inject internal class BundleDetailsViewModel( private val bundles: Repositories.Bundles ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesFragment.kt index a7c4dd29..01e408b5 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesFragment.kt @@ -11,11 +11,11 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentCertificatesBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.certificates.details.CertificateDetailsActivity import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import com.infinum.sentinel.ui.shared.edgefactories.bounce.BounceEdgeEffectFactory -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class CertificatesFragment : @@ -30,7 +30,7 @@ internal class CertificatesFragment : SentinelFragmentCertificatesBinding::bind ) - override val viewModel: CertificatesViewModel by viewModel() + override val viewModel: CertificatesViewModel by viewModels() private val userHeaderAdapter = HeaderAdapter(R.string.sentinel_certificates_user, 0) private val userAdapter = CertificatesAdapter( diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesViewModel.kt index 91d26b94..0ca81290 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/CertificatesViewModel.kt @@ -8,7 +8,9 @@ import com.infinum.sentinel.domain.certificate.models.CertificateParameters import com.infinum.sentinel.domain.certificate.monitor.models.CertificateMonitorParameters import com.infinum.sentinel.ui.shared.base.BaseChildViewModel import kotlinx.coroutines.flow.first +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificatesViewModel( private val collectors: Factories.Collector, private val repository: Repositories.Certificate, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsFragment.kt index e7923332..7fdb0169 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsFragment.kt @@ -7,10 +7,10 @@ import androidx.core.content.ContextCompat import androidx.core.view.isVisible import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentCertificateDetailsBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import java.text.SimpleDateFormat -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class CertificateDetailsFragment : @@ -27,7 +27,7 @@ internal class CertificateDetailsFragment : SentinelFragmentCertificateDetailsBinding::bind ) - override val viewModel: CertificateDetailsViewModel by viewModel() + override val viewModel: CertificateDetailsViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsViewModel.kt index 461651ca..90b27aaf 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/details/CertificateDetailsViewModel.kt @@ -4,7 +4,9 @@ import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.certificate.monitor.models.CertificateMonitorParameters import com.infinum.sentinel.ui.shared.base.BaseChildViewModel import kotlinx.coroutines.flow.first +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificateDetailsViewModel( private val repository: Repositories.Certificate, private val monitor: Repositories.CertificateMonitor diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificateCheckWorker.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificateCheckWorker.kt index ec282966..df2a8264 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificateCheckWorker.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificateCheckWorker.kt @@ -4,29 +4,26 @@ import android.content.Context import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.infinum.sentinel.data.models.raw.certificates.CertificateType -import com.infinum.sentinel.di.LibraryKoinComponent import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.extensions.applicationName -import com.infinum.sentinel.ui.Presentation.Constants.Keys.EXPIRE_IN_AMOUNT -import com.infinum.sentinel.ui.Presentation.Constants.Keys.EXPIRE_IN_UNIT -import com.infinum.sentinel.ui.Presentation.Constants.Keys.NOTIFY_INVALID_NOW -import com.infinum.sentinel.ui.Presentation.Constants.Keys.NOTIFY_TO_EXPIRE +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.notification.NotificationFactory import java.time.temporal.ChronoUnit -import org.koin.core.component.inject internal class CertificateCheckWorker( private val context: Context, - parameters: WorkerParameters -) : CoroutineWorker(context, parameters), LibraryKoinComponent { + parameters: WorkerParameters, + private val collectors: Factories.Collector, + private val notificationFactory: NotificationFactory +) : CoroutineWorker(context, parameters) { companion object { - const val NAME = "sentinel_check_certificates" + const val NAME = "com.infinum.sentinel.ui.certificates.observer.CertificateCheckWorker" } - private val collectors: Factories.Collector by inject() - private val notificationFactory: NotificationFactory by inject() - override suspend fun doWork(): Result { val notifyInvalidNow = inputData.getBoolean(NOTIFY_INVALID_NOW, false) val notifyToExpire = inputData.getBoolean(NOTIFY_TO_EXPIRE, false) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificatesObserver.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificatesObserver.kt index 39708381..614fe22f 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificatesObserver.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/CertificatesObserver.kt @@ -18,7 +18,9 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext +import me.tatarka.inject.annotations.Inject +@Inject internal class CertificatesObserver( private val context: Context, private val collectors: Factories.Collector, 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 688d7020..d0823898 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,20 +10,24 @@ 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.Presentation.Constants.Keys.EXPIRE_IN_AMOUNT -import com.infinum.sentinel.ui.Presentation.Constants.Keys.EXPIRE_IN_UNIT -import com.infinum.sentinel.ui.Presentation.Constants.Keys.NOTIFY_INVALID_NOW -import com.infinum.sentinel.ui.Presentation.Constants.Keys.NOTIFY_TO_EXPIRE +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 java.time.Duration import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map +import me.tatarka.inject.annotations.Inject +@Inject internal class SentinelWorkManager( - private val context: Context + private val context: Context, + private val workerFactory: WorkerFactory ) { companion object { @@ -36,6 +40,7 @@ internal class SentinelWorkManager( context, Configuration.Builder() .setMinimumLoggingLevel(android.util.Log.INFO) + .setWorkerFactory(workerFactory) .build() ) } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkerFactory.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkerFactory.kt new file mode 100644 index 00000000..8fa5a01a --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/certificates/observer/SentinelWorkerFactory.kt @@ -0,0 +1,32 @@ +package com.infinum.sentinel.ui.certificates.observer + +import android.content.Context +import androidx.work.ListenableWorker +import androidx.work.WorkerFactory +import androidx.work.WorkerParameters +import com.infinum.sentinel.domain.Factories +import com.infinum.sentinel.ui.shared.notification.NotificationFactory +import me.tatarka.inject.annotations.Inject + +@Inject +internal class SentinelWorkerFactory( + private val collectors: Factories.Collector, + private val notificationFactory: NotificationFactory +) : WorkerFactory() { + + override fun createWorker( + appContext: Context, + workerClassName: String, + workerParameters: WorkerParameters + ): ListenableWorker? = + when (workerClassName) { + CertificateCheckWorker.NAME -> + CertificateCheckWorker( + appContext, + workerParameters, + collectors, + notificationFactory + ) + else -> null + } +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesActivity.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesActivity.kt index 6c2d708b..4b4497cb 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesActivity.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesActivity.kt @@ -2,7 +2,7 @@ package com.infinum.sentinel.ui.crash import android.os.Bundle import androidx.annotation.RestrictTo -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildActivity @RestrictTo(RestrictTo.Scope.LIBRARY) @@ -14,7 +14,7 @@ internal class CrashesActivity : BaseChildActivity() { supportFragmentManager.beginTransaction() .replace( android.R.id.content, - CrashesFragment.newInstance(intent.getStringExtra(Presentation.Constants.Keys.APPLICATION_NAME)), + CrashesFragment.newInstance(intent.getStringExtra(Constants.Keys.APPLICATION_NAME)), CrashesFragment.TAG ) .commit() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesFragment.kt index a23f1d4f..accf7edf 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesFragment.kt @@ -12,12 +12,12 @@ import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentCrashesBinding import com.infinum.sentinel.extensions.searchView import com.infinum.sentinel.extensions.setup -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.crash.details.CrashDetailsActivity +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import com.infinum.sentinel.ui.shared.edgefactories.bounce.BounceEdgeEffectFactory -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class CrashesFragment : BaseChildFragment(R.layout.sentinel_fragment_crashes) { @@ -26,7 +26,7 @@ internal class CrashesFragment : BaseChildFragment(R.layo fun newInstance(applicationName: String?) = CrashesFragment() .apply { arguments = Bundle().apply { - putString(Presentation.Constants.Keys.APPLICATION_NAME, applicationName) + putString(Constants.Keys.APPLICATION_NAME, applicationName) } } @@ -37,7 +37,7 @@ internal class CrashesFragment : BaseChildFragment(R.layo SentinelFragmentCrashesBinding::bind ) - override val viewModel: CrashesViewModel by viewModel() + override val viewModel: CrashesViewModel by viewModels() private val adapter = CrashesAdapter( onListChanged = { isEmpty -> @@ -47,7 +47,7 @@ internal class CrashesFragment : BaseChildFragment(R.layo startActivity( Intent(requireContext(), CrashDetailsActivity::class.java) .apply { - putExtra(Presentation.Constants.Keys.CRASH_ID, it.id) + putExtra(Constants.Keys.CRASH_ID, it.id) } ) } @@ -58,7 +58,7 @@ internal class CrashesFragment : BaseChildFragment(R.layo override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - applicationName = arguments?.getString(Presentation.Constants.Keys.APPLICATION_NAME) + applicationName = arguments?.getString(Constants.Keys.APPLICATION_NAME) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesViewModel.kt index 52684520..17740b4f 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/CrashesViewModel.kt @@ -8,7 +8,9 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import me.tatarka.inject.annotations.Inject +@Inject internal class CrashesViewModel( private val dao: CrashesDao ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelAnrObserverRunnable.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelAnrObserverRunnable.kt index a54774df..4b75feba 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelAnrObserverRunnable.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelAnrObserverRunnable.kt @@ -11,10 +11,12 @@ import com.infinum.sentinel.extensions.applicationName import com.infinum.sentinel.extensions.asExceptionData import com.infinum.sentinel.ui.shared.notification.NotificationFactory import kotlinx.coroutines.runBlocking +import me.tatarka.inject.annotations.Inject /** * A [Runnable] testing the UI thread every 10s until stop is called explicitly. */ +@Inject internal class SentinelAnrObserverRunnable( private val context: Context, private val notificationFactory: NotificationFactory, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelUiAnrObserver.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelUiAnrObserver.kt index e7990394..639ee803 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelUiAnrObserver.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/anr/SentinelUiAnrObserver.kt @@ -2,10 +2,12 @@ package com.infinum.sentinel.ui.crash.anr import com.infinum.sentinel.Sentinel import java.util.concurrent.ExecutorService +import me.tatarka.inject.annotations.Inject /** * A class observing the UI thread for ANR errors. */ +@Inject internal class SentinelUiAnrObserver( private val observerRunnable: SentinelAnrObserverRunnable, private val executor: ExecutorService diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsActivity.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsActivity.kt index 215e9a42..7f5a2ee3 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsActivity.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsActivity.kt @@ -2,7 +2,7 @@ package com.infinum.sentinel.ui.crash.details import android.os.Bundle import androidx.annotation.RestrictTo -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildActivity @RestrictTo(RestrictTo.Scope.LIBRARY) @@ -11,7 +11,7 @@ internal class CrashDetailsActivity : BaseChildActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - intent?.getLongExtra(Presentation.Constants.Keys.CRASH_ID, -1L) + intent?.getLongExtra(Constants.Keys.CRASH_ID, -1L) ?.takeUnless { it == -1L } ?.let { supportFragmentManager.beginTransaction() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsFragment.kt index a29338e3..6bc7e94f 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsFragment.kt @@ -10,12 +10,12 @@ import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentCrashDetailsBinding import com.infinum.sentinel.databinding.SentinelViewItemThreadStateBinding import com.infinum.sentinel.extensions.shareText -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.extensions.viewModels +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import java.text.SimpleDateFormat import java.util.Date -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class CrashDetailsFragment : @@ -24,7 +24,7 @@ internal class CrashDetailsFragment : companion object { fun newInstance(crashId: Long) = CrashDetailsFragment().apply { arguments = Bundle().apply { - putLong(Presentation.Constants.Keys.CRASH_ID, crashId) + putLong(Constants.Keys.CRASH_ID, crashId) } } @@ -35,14 +35,14 @@ internal class CrashDetailsFragment : SentinelFragmentCrashDetailsBinding::bind ) - override val viewModel: CrashDetailsViewModel by viewModel() + override val viewModel: CrashDetailsViewModel by viewModels() private var crashId: Long? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - crashId = arguments?.getLong(Presentation.Constants.Keys.CRASH_ID) + crashId = arguments?.getLong(Constants.Keys.CRASH_ID) crashId?.let { viewModel.setCrashId(it) } ?: activity?.finish() } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsViewModel.kt index 99dd699e..ed5cae6e 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/details/CrashDetailsViewModel.kt @@ -10,7 +10,9 @@ import com.infinum.sentinel.extensions.formatter import com.infinum.sentinel.ui.shared.base.BaseChildViewModel import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map +import me.tatarka.inject.annotations.Inject +@Inject internal class CrashDetailsViewModel( private val crashMonitor: Repositories.CrashMonitor, private val dao: CrashesDao, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/handler/SentinelUncaughtExceptionHandler.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/handler/SentinelUncaughtExceptionHandler.kt index 490d90de..0edb2ce6 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/handler/SentinelUncaughtExceptionHandler.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/crash/handler/SentinelUncaughtExceptionHandler.kt @@ -9,7 +9,9 @@ import com.infinum.sentinel.extensions.asExceptionData import com.infinum.sentinel.extensions.asThreadData import com.infinum.sentinel.ui.shared.notification.NotificationFactory import kotlinx.coroutines.runBlocking +import me.tatarka.inject.annotations.Inject +@Inject internal class SentinelUncaughtExceptionHandler( private val context: Context, private val notificationFactory: NotificationFactory, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelFragment.kt index 7fd26b50..4f83d830 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelFragment.kt @@ -9,6 +9,7 @@ import com.google.android.material.shape.ShapeAppearanceModel import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentBinding import com.infinum.sentinel.extensions.shareText +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.main.application.ApplicationFragment import com.infinum.sentinel.ui.main.device.DeviceFragment import com.infinum.sentinel.ui.main.permissions.PermissionsFragment @@ -18,7 +19,6 @@ import com.infinum.sentinel.ui.settings.SettingsActivity import com.infinum.sentinel.ui.shared.base.BaseFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import com.infinum.sentinel.ui.shared.edgetreatment.ScissorsEdgeTreatment -import org.koin.androidx.viewmodel.ext.android.viewModel @Suppress("TooManyFunctions") @RestrictTo(RestrictTo.Scope.LIBRARY) @@ -28,7 +28,7 @@ internal class SentinelFragment : BaseFragment(R.l const val TAG: String = "SentinelFragment" } - override val viewModel: SentinelViewModel by viewModel() + override val viewModel: SentinelViewModel by viewModels() override val binding: SentinelFragmentBinding by viewBinding( SentinelFragmentBinding::bind diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelViewModel.kt index 23677c9d..dbf36251 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/SentinelViewModel.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map +import me.tatarka.inject.annotations.Inject +@Inject internal class SentinelViewModel( private val collectors: Factories.Collector, private val formatters: Factories.Formatter, diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationFragment.kt index 65700c18..be389583 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationFragment.kt @@ -3,9 +3,9 @@ package com.infinum.sentinel.ui.main.application import androidx.annotation.RestrictTo import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentApplicationBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class ApplicationFragment : @@ -20,7 +20,7 @@ internal class ApplicationFragment : SentinelFragmentApplicationBinding::bind ) - override val viewModel: ApplicationViewModel by viewModel() + override val viewModel: ApplicationViewModel by viewModels() override fun onState(state: ApplicationState) = when (state) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationViewModel.kt index 6cd5eb6e..02dd4763 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/application/ApplicationViewModel.kt @@ -2,7 +2,9 @@ package com.infinum.sentinel.ui.main.application import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class ApplicationViewModel( private val collectors: Factories.Collector ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceFragment.kt index 6f86c85b..d4414618 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceFragment.kt @@ -3,9 +3,9 @@ package com.infinum.sentinel.ui.main.device import androidx.annotation.RestrictTo import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentDeviceBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class DeviceFragment : BaseChildFragment(R.layout.sentinel_fragment_device) { @@ -19,7 +19,7 @@ internal class DeviceFragment : BaseChildFragment(R.layout SentinelFragmentDeviceBinding::bind ) - override val viewModel: DeviceViewModel by viewModel() + override val viewModel: DeviceViewModel by viewModels() override fun onState(state: DeviceState) = when (state) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceViewModel.kt index 782d8912..ef3342c5 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/device/DeviceViewModel.kt @@ -2,7 +2,9 @@ package com.infinum.sentinel.ui.main.device import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class DeviceViewModel( private val collectors: Factories.Collector ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsFragment.kt index 93a7a61a..9d102b5c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsFragment.kt @@ -6,9 +6,9 @@ import com.infinum.sentinel.R import com.infinum.sentinel.databinding.SentinelFragmentPermissionsBinding import com.infinum.sentinel.databinding.SentinelViewItemCheckableBinding import com.infinum.sentinel.extensions.copyToClipboard +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class PermissionsFragment : @@ -23,7 +23,7 @@ internal class PermissionsFragment : SentinelFragmentPermissionsBinding::bind ) - override val viewModel: PermissionsViewModel by viewModel() + override val viewModel: PermissionsViewModel by viewModels() override fun onState(state: PermissionsState) = when (state) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsViewModel.kt index 99580b92..68bba356 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/permissions/PermissionsViewModel.kt @@ -2,7 +2,9 @@ package com.infinum.sentinel.ui.main.permissions import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class PermissionsViewModel( private val collectors: Factories.Collector ) : BaseChildViewModel() { 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 539fc2c1..8ec54649 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 @@ -10,10 +10,10 @@ import com.infinum.sentinel.databinding.SentinelFragmentPreferencesBinding import com.infinum.sentinel.databinding.SentinelViewItemPreferenceBinding import com.infinum.sentinel.databinding.SentinelViewItemTextBinding import com.infinum.sentinel.extensions.copyToClipboard +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.main.preferences.editor.PreferenceEditorContract import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class PreferencesFragment : @@ -30,7 +30,7 @@ internal class PreferencesFragment : SentinelFragmentPreferencesBinding::bind ) - override val viewModel: PreferencesViewModel by viewModel() + override val viewModel: PreferencesViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) 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 4f8751d8..0299b8ce 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 @@ -5,7 +5,9 @@ import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.preference.models.PreferenceParameters import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class PreferencesViewModel( private val collectors: Factories.Collector, private val repository: Repositories.Preference diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorContract.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorContract.kt index 554ff64b..a02b2425 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorContract.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorContract.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.content.Context import android.content.Intent import androidx.activity.result.contract.ActivityResultContract -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.ui.shared.Constants internal class PreferenceEditorContract : ActivityResultContract() { @@ -14,7 +14,7 @@ internal class PreferenceEditorContract : ActivityResultContract( override fun parseResult(resultCode: Int, intent: Intent?): Boolean = if (resultCode == Activity.RESULT_OK) { intent?.getBooleanExtra( - Presentation.Constants.Keys.SHOULD_REFRESH, + Constants.Keys.SHOULD_REFRESH, false ) ?: false } else { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorFragment.kt index 5444dfa8..dff577e1 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorFragment.kt @@ -17,10 +17,10 @@ import com.infinum.sentinel.R import com.infinum.sentinel.data.models.raw.PreferenceType import com.infinum.sentinel.databinding.SentinelFragmentPreferenceEditorBinding import com.infinum.sentinel.databinding.SentinelViewItemInputBinding -import com.infinum.sentinel.ui.Presentation +import com.infinum.sentinel.extensions.viewModels +import com.infinum.sentinel.ui.shared.Constants import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class PreferenceEditorFragment : @@ -37,7 +37,7 @@ internal class PreferenceEditorFragment : SentinelFragmentPreferenceEditorBinding::bind ) - override val viewModel: PreferenceEditorViewModel by viewModel() + override val viewModel: PreferenceEditorViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -269,7 +269,7 @@ internal class PreferenceEditorFragment : it.setResult( Activity.RESULT_OK, Intent().apply { - putExtra(Presentation.Constants.Keys.SHOULD_REFRESH, true) + putExtra(Constants.Keys.SHOULD_REFRESH, true) } ) it.finish() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorViewModel.kt index f9c9e648..cfa59ace 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/preferences/editor/PreferenceEditorViewModel.kt @@ -3,7 +3,9 @@ package com.infinum.sentinel.ui.main.preferences.editor import com.infinum.sentinel.domain.Repositories import com.infinum.sentinel.domain.preference.models.PreferenceParameters import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class PreferenceEditorViewModel( private val repository: Repositories.Preference ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsFragment.kt index e99a1bbe..daacce99 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsFragment.kt @@ -7,9 +7,9 @@ import com.infinum.sentinel.R import com.infinum.sentinel.Sentinel import com.infinum.sentinel.databinding.SentinelFragmentToolsBinding import com.infinum.sentinel.databinding.SentinelViewItemButtonBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class ToolsFragment : BaseChildFragment(R.layout.sentinel_fragment_tools) { @@ -23,7 +23,7 @@ internal class ToolsFragment : BaseChildFragment(R.layout.s SentinelFragmentToolsBinding::bind ) - override val viewModel: ToolsViewModel by viewModel() + override val viewModel: ToolsViewModel by viewModels() override fun onState(state: ToolsState) = when (state) { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsViewModel.kt index 88c7dee7..f3bc3996 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/main/tools/ToolsViewModel.kt @@ -2,7 +2,9 @@ package com.infinum.sentinel.ui.main.tools import com.infinum.sentinel.domain.Factories import com.infinum.sentinel.ui.shared.base.BaseChildViewModel +import me.tatarka.inject.annotations.Inject +@Inject internal class ToolsViewModel( private val collectors: Factories.Collector ) : BaseChildViewModel() { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsFragment.kt index 5bd3098d..020e8cf3 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsFragment.kt @@ -10,11 +10,11 @@ import com.infinum.sentinel.data.models.local.TriggerEntity import com.infinum.sentinel.data.models.memory.formats.FormatType import com.infinum.sentinel.data.models.memory.triggers.TriggerType import com.infinum.sentinel.databinding.SentinelFragmentSettingsBinding +import com.infinum.sentinel.extensions.viewModels import com.infinum.sentinel.ui.shared.base.BaseChildFragment import com.infinum.sentinel.ui.shared.delegates.viewBinding import java.time.temporal.ChronoUnit import kotlin.math.roundToInt -import org.koin.androidx.viewmodel.ext.android.viewModel @RestrictTo(RestrictTo.Scope.LIBRARY) internal class SettingsFragment : BaseChildFragment(R.layout.sentinel_fragment_settings) { @@ -31,7 +31,7 @@ internal class SettingsFragment : BaseChildFragment(R.la SentinelFragmentSettingsBinding::bind ) - override val viewModel: SettingsViewModel by viewModel() + override val viewModel: SettingsViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsViewModel.kt index e8ce94d2..1f2b9f65 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/settings/SettingsViewModel.kt @@ -18,8 +18,10 @@ import com.infinum.sentinel.ui.crash.handler.SentinelExceptionHandler import com.infinum.sentinel.ui.shared.base.BaseChildViewModel import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.flowOn +import me.tatarka.inject.annotations.Inject @Suppress("LongParameterList") +@Inject internal class SettingsViewModel( private val triggers: Repositories.Triggers, private val formats: Repositories.Formats, 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 new file mode 100644 index 00000000..3e4004f9 --- /dev/null +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/Constants.kt @@ -0,0 +1,18 @@ +package com.infinum.sentinel.ui.shared + +internal object Constants { + const val BYTE_MULTIPLIER = 1000 + const val SHARE_MIME_TYPE = "text/plain" + const val NOTIFICATIONS_CHANNEL_ID = "sentinel" + + object Keys { + const val BUNDLE_ID = "KEY_BUNDLE_ID" + const val SHOULD_REFRESH: String = "KEY_SHOULD_REFRESH" + const val APPLICATION_NAME: String = "KEY_APPLICATION_NAME" + const val CRASH_ID: String = "KEY_CRASH_ID" + const val NOTIFY_INVALID_NOW: String = "KEY_NOTIFY_INVALID_NOW" + 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" + } +} diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseChildFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseChildFragment.kt index 8e48d968..6e302e38 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseChildFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseChildFragment.kt @@ -7,12 +7,11 @@ import androidx.annotation.LayoutRes import androidx.annotation.RestrictTo import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding -import com.infinum.sentinel.di.LibraryKoinComponent @RestrictTo(RestrictTo.Scope.LIBRARY) internal abstract class BaseChildFragment( @LayoutRes contentLayoutId: Int -) : Fragment(contentLayoutId), BaseView, LibraryKoinComponent { +) : Fragment(contentLayoutId), BaseView { abstract val binding: ViewBinding diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseFragment.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseFragment.kt index b9c12591..2fcee750 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseFragment.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseFragment.kt @@ -14,12 +14,11 @@ import androidx.annotation.RestrictTo import androidx.fragment.app.DialogFragment import androidx.viewbinding.ViewBinding import com.infinum.sentinel.R -import com.infinum.sentinel.di.LibraryKoinComponent @RestrictTo(RestrictTo.Scope.LIBRARY) internal abstract class BaseFragment( @LayoutRes private val contentLayoutId: Int -) : DialogFragment(), BaseView, LibraryKoinComponent { +) : DialogFragment(), BaseView { abstract val binding: ViewBinding @@ -31,7 +30,8 @@ internal abstract class BaseFragment( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { window?.let { it.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND) - it.attributes.blurBehindRadius = resources.getDimensionPixelSize(R.dimen.sentinel_blur_radius) + it.attributes.blurBehindRadius = + resources.getDimensionPixelSize(R.dimen.sentinel_blur_radius) } } window?.let { diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseViewModel.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseViewModel.kt index 2b65bb22..bc360bef 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseViewModel.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/base/BaseViewModel.kt @@ -3,7 +3,6 @@ package com.infinum.sentinel.ui.shared.base import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.infinum.sentinel.di.LibraryKoinComponent import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -18,7 +17,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -internal abstract class BaseViewModel : ViewModel(), LibraryKoinComponent { +internal abstract class BaseViewModel : ViewModel() { private val supervisorJob = SupervisorJob() diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/NotificationIntentFactory.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/NotificationIntentFactory.kt index 8a2bcefb..e91305e0 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/NotificationIntentFactory.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/NotificationIntentFactory.kt @@ -2,11 +2,13 @@ package com.infinum.sentinel.ui.shared.notification import android.content.Context import android.content.Intent -import com.infinum.sentinel.ui.Presentation import com.infinum.sentinel.ui.certificates.CertificatesActivity import com.infinum.sentinel.ui.crash.CrashesActivity import com.infinum.sentinel.ui.crash.details.CrashDetailsActivity +import com.infinum.sentinel.ui.shared.Constants +import me.tatarka.inject.annotations.Inject +@Inject internal class NotificationIntentFactory( private val context: Context ) : IntentFactory { @@ -15,11 +17,11 @@ internal class NotificationIntentFactory( arrayOf( Intent(context, CrashesActivity::class.java) .apply { - putExtra(Presentation.Constants.Keys.APPLICATION_NAME, applicationName) + putExtra(Constants.Keys.APPLICATION_NAME, applicationName) }, Intent(context, CrashDetailsActivity::class.java) .apply { - putExtra(Presentation.Constants.Keys.CRASH_ID, id) + putExtra(Constants.Keys.CRASH_ID, id) } ) @@ -27,7 +29,7 @@ internal class NotificationIntentFactory( arrayOf( Intent(context, CertificatesActivity::class.java) .apply { - putExtra(Presentation.Constants.Keys.APPLICATION_NAME, applicationName) + putExtra(Constants.Keys.APPLICATION_NAME, applicationName) } ) } diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/SystemNotificationFactory.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/SystemNotificationFactory.kt index 77e78c70..45d34d6e 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/SystemNotificationFactory.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/shared/notification/SystemNotificationFactory.kt @@ -11,8 +11,10 @@ import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat import com.infinum.sentinel.R import com.infinum.sentinel.data.models.local.CrashEntity -import com.infinum.sentinel.ui.Presentation.Constants.NOTIFICATIONS_CHANNEL_ID +import com.infinum.sentinel.ui.shared.Constants.NOTIFICATIONS_CHANNEL_ID +import me.tatarka.inject.annotations.Inject +@Inject internal class SystemNotificationFactory( private val context: Context, private val intentFactory: IntentFactory diff --git a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/tools/CrashMonitorTool.kt b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/tools/CrashMonitorTool.kt index 3853426c..41ee8e6c 100644 --- a/sentinel/src/main/kotlin/com/infinum/sentinel/ui/tools/CrashMonitorTool.kt +++ b/sentinel/src/main/kotlin/com/infinum/sentinel/ui/tools/CrashMonitorTool.kt @@ -7,8 +7,8 @@ import android.view.View import androidx.annotation.StringRes import com.infinum.sentinel.R import com.infinum.sentinel.Sentinel -import com.infinum.sentinel.ui.Presentation import com.infinum.sentinel.ui.crash.CrashesActivity +import com.infinum.sentinel.ui.shared.Constants /** * Specific wrapper tool that monitors crashes for the application which implemented Sentinel. @@ -22,7 +22,7 @@ internal data class CrashMonitorTool( CrashesActivity::class.java ).apply { putExtra( - Presentation.Constants.Keys.APPLICATION_NAME, + Constants.Keys.APPLICATION_NAME, ( it.context.packageManager.getApplicationLabel( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {