android: add core common module logging crashlytics and feature flags
This commit is contained in:
@@ -6,6 +6,7 @@ plugins {
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
id("com.google.dagger.hilt.android")
|
||||
id("com.google.gms.google-services")
|
||||
id("com.google.firebase.crashlytics")
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -19,6 +20,10 @@ android {
|
||||
versionCode = 1
|
||||
versionName = "0.1.0"
|
||||
buildConfigField("String", "API_BASE_URL", "\"https://chat.daemonlord.ru/\"")
|
||||
buildConfigField("String", "API_VERSION_HEADER", "\"2026-03\"")
|
||||
buildConfigField("boolean", "FEATURE_ACCOUNT_MANAGEMENT", "true")
|
||||
buildConfigField("boolean", "FEATURE_TWO_FACTOR", "true")
|
||||
buildConfigField("boolean", "FEATURE_MEDIA_GALLERY", "true")
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
@@ -62,6 +67,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core:common"))
|
||||
implementation(platform("com.google.firebase:firebase-bom:34.10.0"))
|
||||
|
||||
implementation("androidx.core:core-ktx:1.15.0")
|
||||
@@ -98,6 +104,8 @@ dependencies {
|
||||
kapt("com.google.dagger:hilt-compiler:2.52")
|
||||
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
|
||||
implementation("com.google.firebase:firebase-messaging")
|
||||
implementation("com.google.firebase:firebase-crashlytics")
|
||||
implementation("com.jakewharton.timber:timber:5.0.1")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
|
||||
|
||||
@@ -5,14 +5,20 @@ import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import coil.disk.DiskCache
|
||||
import coil.memory.MemoryCache
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import ru.daemonlord.messenger.core.notifications.NotificationChannels
|
||||
import java.io.File
|
||||
import timber.log.Timber
|
||||
|
||||
@HiltAndroidApp
|
||||
class MessengerApplication : Application(), ImageLoaderFactory {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
}
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
|
||||
NotificationChannels.ensureCreated(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package ru.daemonlord.messenger.core.logging
|
||||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import timber.log.Timber
|
||||
|
||||
@Singleton
|
||||
class TimberAppLogger @Inject constructor(
|
||||
private val crashlytics: FirebaseCrashlytics,
|
||||
) : AppLogger {
|
||||
|
||||
override fun d(tag: String, message: String) {
|
||||
Timber.tag(tag).d(message)
|
||||
}
|
||||
|
||||
override fun i(tag: String, message: String) {
|
||||
Timber.tag(tag).i(message)
|
||||
}
|
||||
|
||||
override fun w(tag: String, message: String, throwable: Throwable?) {
|
||||
if (throwable != null) {
|
||||
Timber.tag(tag).w(throwable, message)
|
||||
crashlytics.recordException(throwable)
|
||||
} else {
|
||||
Timber.tag(tag).w(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun e(tag: String, message: String, throwable: Throwable?) {
|
||||
if (throwable != null) {
|
||||
Timber.tag(tag).e(throwable, message)
|
||||
crashlytics.recordException(throwable)
|
||||
} else {
|
||||
Timber.tag(tag).e(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package ru.daemonlord.messenger.core.network
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import ru.daemonlord.messenger.BuildConfig
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ApiVersionInterceptor @Inject constructor() : Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request().newBuilder()
|
||||
.header("X-Api-Version", BuildConfig.API_VERSION_HEADER)
|
||||
.build()
|
||||
return chain.proceed(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package ru.daemonlord.messenger.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import ru.daemonlord.messenger.BuildConfig
|
||||
import ru.daemonlord.messenger.core.feature.FeatureFlags
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object FeatureFlagsModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFeatureFlags(): FeatureFlags {
|
||||
return FeatureFlags(
|
||||
accountManagementEnabled = BuildConfig.FEATURE_ACCOUNT_MANAGEMENT,
|
||||
twoFactorEnabled = BuildConfig.FEATURE_TWO_FACTOR,
|
||||
mediaGalleryEnabled = BuildConfig.FEATURE_MEDIA_GALLERY,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package ru.daemonlord.messenger.di
|
||||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import ru.daemonlord.messenger.core.logging.AppLogger
|
||||
import ru.daemonlord.messenger.core.logging.TimberAppLogger
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class LoggingModule {
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract fun bindAppLogger(logger: TimberAppLogger): AppLogger
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideCrashlytics(): FirebaseCrashlytics = FirebaseCrashlytics.getInstance()
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,13 @@ import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import ru.daemonlord.messenger.BuildConfig
|
||||
import ru.daemonlord.messenger.core.network.AuthHeaderInterceptor
|
||||
import ru.daemonlord.messenger.core.network.ApiVersionInterceptor
|
||||
import ru.daemonlord.messenger.core.network.TokenRefreshAuthenticator
|
||||
import ru.daemonlord.messenger.data.auth.api.AuthApiService
|
||||
import ru.daemonlord.messenger.data.chat.api.ChatApiService
|
||||
import ru.daemonlord.messenger.data.media.api.MediaApiService
|
||||
import ru.daemonlord.messenger.data.message.api.MessageApiService
|
||||
import ru.daemonlord.messenger.data.user.api.UserApiService
|
||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Singleton
|
||||
@@ -87,11 +89,13 @@ object NetworkModule {
|
||||
@Singleton
|
||||
fun provideApiClient(
|
||||
loggingInterceptor: HttpLoggingInterceptor,
|
||||
apiVersionInterceptor: ApiVersionInterceptor,
|
||||
authHeaderInterceptor: AuthHeaderInterceptor,
|
||||
tokenRefreshAuthenticator: TokenRefreshAuthenticator,
|
||||
): OkHttpClient {
|
||||
return OkHttpClient.Builder()
|
||||
.addInterceptor(loggingInterceptor)
|
||||
.addInterceptor(apiVersionInterceptor)
|
||||
.addInterceptor(authHeaderInterceptor)
|
||||
.authenticator(tokenRefreshAuthenticator)
|
||||
.connectTimeout(20, TimeUnit.SECONDS)
|
||||
@@ -137,4 +141,10 @@ object NetworkModule {
|
||||
fun provideMediaApiService(retrofit: Retrofit): MediaApiService {
|
||||
return retrofit.create(MediaApiService::class.java)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUserApiService(retrofit: Retrofit): UserApiService {
|
||||
return retrofit.create(UserApiService::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
plugins {
|
||||
id("com.android.application") version "8.7.2" apply false
|
||||
id("com.android.library") version "8.7.2" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.0.21" apply false
|
||||
id("org.jetbrains.kotlin.jvm") version "2.0.21" apply false
|
||||
id("org.jetbrains.kotlin.plugin.compose") version "2.0.21" apply false
|
||||
id("com.google.dagger.hilt.android") version "2.52" apply false
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version "2.0.21" apply false
|
||||
id("org.jetbrains.kotlin.kapt") version "2.0.21" apply false
|
||||
id("com.google.gms.google-services") version "4.4.4" apply false
|
||||
id("com.google.firebase.crashlytics") version "3.0.3" apply false
|
||||
}
|
||||
|
||||
7
android/core/common/build.gradle.kts
Normal file
7
android/core/common/build.gradle.kts
Normal file
@@ -0,0 +1,7 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ru.daemonlord.messenger.core.feature
|
||||
|
||||
data class FeatureFlags(
|
||||
val accountManagementEnabled: Boolean,
|
||||
val twoFactorEnabled: Boolean,
|
||||
val mediaGalleryEnabled: Boolean,
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package ru.daemonlord.messenger.core.logging
|
||||
|
||||
interface AppLogger {
|
||||
fun d(tag: String, message: String)
|
||||
fun i(tag: String, message: String)
|
||||
fun w(tag: String, message: String, throwable: Throwable? = null)
|
||||
fun e(tag: String, message: String, throwable: Throwable? = null)
|
||||
}
|
||||
@@ -16,3 +16,4 @@ dependencyResolutionManagement {
|
||||
|
||||
rootProject.name = "MessengerAndroid"
|
||||
include(":app")
|
||||
include(":core:common")
|
||||
|
||||
Reference in New Issue
Block a user