mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-23 12:45:01 +01:00
by replacing net.zetetic:android-database-sqlcipher with net.zetetic:sqlcipher-android which should hopefully solve the error Exception java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/~~HfdEzwuB9IXXVa0Fvds_Kw==/com.nextcloud.talk2-yCC7T_sy5lQWb9w17SZlVQ==/base.apk!/lib/arm64-v8a/libsqlcipher.so" (new hash type from the future?) at java.lang.Runtime.loadLibrary0 (Runtime.java:1081) at java.lang.Runtime.loadLibrary0 (Runtime.java:1003) at java.lang.System.loadLibrary (System.java:1765) at net.sqlcipher.database.SQLiteDatabase$1.loadLibraries (SQLiteDatabase.java:230) at net.sqlcipher.database.SQLiteDatabase.loadLibs (SQLiteDatabase.java:247) at net.sqlcipher.database.SQLiteDatabase.loadLibs (SQLiteDatabase.java:226) at net.sqlcipher.database.SQLiteDatabase.loadLibs (SQLiteDatabase.java:219) at net.sqlcipher.database.SupportHelper.<init> (SupportHelper.java:31) at net.sqlcipher.database.SupportFactory.create (SupportFactory.java:43) at androidx.room.RoomConnectionManager.<init> (RoomConnectionManager.android.kt:68) at androidx.room.RoomDatabase.createConnectionManager$room_runtime_release (RoomDatabase.android.kt:318) at androidx.room.RoomDatabase.init (RoomDatabase.android.kt:229) at androidx.room.RoomDatabase$Builder.build (RoomDatabase.android.kt:1769) at com.nextcloud.talk.data.source.local.TalkDatabase$Companion.build (TalkDatabase.kt:136) at com.nextcloud.talk.data.source.local.TalkDatabase$Companion.getInstance (TalkDatabase.kt:89) at com.nextcloud.talk.data.source.local.TalkDatabase.getInstance (Unknown Source:2) at com.nextcloud.talk.dagger.modules.DatabaseModule.provideTalkDatabase (DatabaseModule.java:47) at com.nextcloud.talk.dagger.modules.DatabaseModule_ProvideTalkDatabaseFactory.provideTalkDatabase (DatabaseModule_ProvideTalkDatabaseFactory.java:56) at com.nextcloud.talk.dagger.modules.DatabaseModule_ProvideTalkDatabaseFactory.get (DatabaseModule_ProvideTalkDatabaseFactory.java:46) at com.nextcloud.talk.dagger.modules.DatabaseModule_ProvideTalkDatabaseFactory.get (DatabaseModule_ProvideTalkDatabaseFactory.java:14) at dagger.internal.DoubleCheck.getSynchronized (DoubleCheck.java:54) at dagger.internal.DoubleCheck.get (DoubleCheck.java:45) at com.nextcloud.talk.dagger.modules.RepositoryModule_ProvideUsersRepositoryFactory.get (RepositoryModule_ProvideUsersRepositoryFactory.java:42) at com.nextcloud.talk.dagger.modules.RepositoryModule_ProvideUsersRepositoryFactory.get (RepositoryModule_ProvideUsersRepositoryFactory.java:13) at com.nextcloud.talk.utils.database.user.UserModule_Companion_ProvideUserManagerFactory.get (UserModule_Companion_ProvideUserManagerFactory.java:39) at com.nextcloud.talk.utils.database.user.UserModule_Companion_ProvideUserManagerFactory.get (UserModule_Companion_ProvideUserManagerFactory.java:13) at com.nextcloud.talk.dagger.modules.RestModule_ProvideKeyManagerFactory.get (RestModule_ProvideKeyManagerFactory.java:46) at com.nextcloud.talk.dagger.modules.RestModule_ProvideKeyManagerFactory.get (RestModule_ProvideKeyManagerFactory.java:14) at dagger.internal.DoubleCheck.getSynchronized (DoubleCheck.java:54) at dagger.internal.DoubleCheck.get (DoubleCheck.java:45) at com.nextcloud.talk.dagger.modules.RestModule_ProvideSslSocketFactoryCompatFactory.get (RestModule_ProvideSslSocketFactoryCompatFactory.java:46) at com.nextcloud.talk.dagger.modules.RestModule_ProvideSslSocketFactoryCompatFactory.get (RestModule_ProvideSslSocketFactoryCompatFactory.java:14) at dagger.internal.DoubleCheck.getSynchronized (DoubleCheck.java:54) at dagger.internal.DoubleCheck.get (DoubleCheck.java:45) at com.nextcloud.talk.dagger.modules.RestModule_ProvideHttpClientFactory.get (RestModule_ProvideHttpClientFactory.java:69) at com.nextcloud.talk.dagger.modules.RestModule_ProvideHttpClientFactory.get (RestModule_ProvideHttpClientFactory.java:19) at dagger.internal.DoubleCheck.getSynchronized (DoubleCheck.java:54) at dagger.internal.DoubleCheck.get (DoubleCheck.java:45) at com.nextcloud.talk.application.DaggerNextcloudTalkApplicationComponent$NextcloudTalkApplicationComponentImpl.injectNextcloudTalkApplication (DaggerNextcloudTalkApplicationComponent.java:1629) at com.nextcloud.talk.application.DaggerNextcloudTalkApplicationComponent$NextcloudTalkApplicationComponentImpl.inject (DaggerNextcloudTalkApplicationComponent.java:997) at com.nextcloud.talk.application.NextcloudTalkApplication.onCreate (NextcloudTalkApplication.kt:147) at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1386) at android.app.ActivityThread.handleBindApplication (ActivityThread.java:7504) at android.app.ActivityThread.-$$Nest$mhandleBindApplication (Unknown Source) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2416) at android.os.Handler.dispatchMessage (Handler.java:107) at android.os.Looper.loopOnce (Looper.java:232) at android.os.Looper.loop (Looper.java:317) at android.app.ActivityThread.main (ActivityThread.java:8705) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:580) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:886) which is reported in gplay console pre publish checks and blocks new releases Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
253 lines
8.7 KiB
Kotlin
253 lines
8.7 KiB
Kotlin
/*
|
|
* Nextcloud Talk - Android Client
|
|
*
|
|
* SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
|
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
|
|
* SPDX-FileCopyrightText: 2022 Tim Krüger <t@timkrueger.me>
|
|
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
package com.nextcloud.talk.application
|
|
|
|
import android.content.Context
|
|
import android.os.Build.VERSION.SDK_INT
|
|
import android.os.Build.VERSION_CODES.P
|
|
import android.util.Log
|
|
import androidx.appcompat.app.AppCompatDelegate
|
|
import androidx.emoji2.bundled.BundledEmojiCompatConfig
|
|
import androidx.emoji2.text.EmojiCompat
|
|
import androidx.lifecycle.LifecycleObserver
|
|
import androidx.multidex.MultiDex
|
|
import androidx.multidex.MultiDexApplication
|
|
import androidx.work.ExistingPeriodicWorkPolicy
|
|
import androidx.work.OneTimeWorkRequest
|
|
import androidx.work.PeriodicWorkRequest
|
|
import androidx.work.WorkManager
|
|
import autodagger.AutoComponent
|
|
import autodagger.AutoInjector
|
|
import coil.Coil
|
|
import coil.ImageLoader
|
|
import coil.decode.GifDecoder
|
|
import coil.decode.ImageDecoderDecoder
|
|
import coil.decode.SvgDecoder
|
|
import coil.memory.MemoryCache
|
|
import coil.util.DebugLogger
|
|
import com.nextcloud.talk.BuildConfig
|
|
import com.nextcloud.talk.dagger.modules.BusModule
|
|
import com.nextcloud.talk.dagger.modules.ContextModule
|
|
import com.nextcloud.talk.dagger.modules.DaosModule
|
|
import com.nextcloud.talk.dagger.modules.DatabaseModule
|
|
import com.nextcloud.talk.dagger.modules.ManagerModule
|
|
import com.nextcloud.talk.dagger.modules.RepositoryModule
|
|
import com.nextcloud.talk.dagger.modules.RestModule
|
|
import com.nextcloud.talk.dagger.modules.UtilsModule
|
|
import com.nextcloud.talk.dagger.modules.ViewModelModule
|
|
import com.nextcloud.talk.filebrowser.webdav.DavUtils
|
|
import com.nextcloud.talk.jobs.AccountRemovalWorker
|
|
import com.nextcloud.talk.jobs.CapabilitiesWorker
|
|
import com.nextcloud.talk.jobs.SignalingSettingsWorker
|
|
import com.nextcloud.talk.jobs.WebsocketConnectionsWorker
|
|
import com.nextcloud.talk.ui.theme.ThemeModule
|
|
import com.nextcloud.talk.utils.ClosedInterfaceImpl
|
|
import com.nextcloud.talk.utils.DeviceUtils
|
|
import com.nextcloud.talk.utils.NotificationUtils
|
|
import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule
|
|
import com.nextcloud.talk.utils.database.user.UserModule
|
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
|
import com.vanniktech.emoji.EmojiManager
|
|
import com.vanniktech.emoji.google.GoogleEmojiProvider
|
|
import de.cotech.hw.SecurityKeyManager
|
|
import de.cotech.hw.SecurityKeyManagerConfig
|
|
import okhttp3.OkHttpClient
|
|
import org.conscrypt.Conscrypt
|
|
import org.webrtc.PeerConnectionFactory
|
|
import java.security.Security
|
|
import java.util.concurrent.TimeUnit
|
|
import javax.inject.Inject
|
|
import javax.inject.Singleton
|
|
|
|
@AutoComponent(
|
|
modules = [
|
|
BusModule::class,
|
|
ContextModule::class,
|
|
DatabaseModule::class,
|
|
RestModule::class,
|
|
UserModule::class,
|
|
ArbitraryStorageModule::class,
|
|
ViewModelModule::class,
|
|
RepositoryModule::class,
|
|
UtilsModule::class,
|
|
ThemeModule::class,
|
|
ManagerModule::class,
|
|
DaosModule::class
|
|
]
|
|
)
|
|
@Singleton
|
|
@AutoInjector(NextcloudTalkApplication::class)
|
|
class NextcloudTalkApplication :
|
|
MultiDexApplication(),
|
|
LifecycleObserver {
|
|
//region Fields (components)
|
|
lateinit var componentApplication: NextcloudTalkApplicationComponent
|
|
private set
|
|
//endregion
|
|
|
|
//region Getters
|
|
|
|
@Inject
|
|
lateinit var appPreferences: AppPreferences
|
|
|
|
@Inject
|
|
lateinit var okHttpClient: OkHttpClient
|
|
//endregion
|
|
|
|
//region private methods
|
|
private fun initializeWebRtc() {
|
|
try {
|
|
PeerConnectionFactory.initialize(
|
|
PeerConnectionFactory.InitializationOptions.builder(this)
|
|
.createInitializationOptions()
|
|
)
|
|
} catch (e: UnsatisfiedLinkError) {
|
|
Log.w(TAG, e)
|
|
}
|
|
}
|
|
|
|
//endregion
|
|
|
|
//region Overridden methods
|
|
override fun onCreate() {
|
|
Log.d(TAG, "onCreate")
|
|
sharedApplication = this
|
|
|
|
val securityKeyManager = SecurityKeyManager.getInstance()
|
|
val securityKeyConfig = SecurityKeyManagerConfig.Builder()
|
|
.setEnableDebugLogging(BuildConfig.DEBUG)
|
|
.build()
|
|
securityKeyManager.init(this, securityKeyConfig)
|
|
|
|
initializeWebRtc()
|
|
buildComponent()
|
|
DavUtils.registerCustomFactories()
|
|
|
|
Security.insertProviderAt(Conscrypt.newProvider(), 1)
|
|
|
|
componentApplication.inject(this)
|
|
|
|
Coil.setImageLoader(buildDefaultImageLoader())
|
|
setAppTheme(appPreferences.theme)
|
|
super.onCreate()
|
|
|
|
ClosedInterfaceImpl().providerInstallerInstallIfNeededAsync()
|
|
DeviceUtils.ignoreSpecialBatteryFeatures()
|
|
|
|
initWorkers()
|
|
|
|
val config = BundledEmojiCompatConfig(this)
|
|
config.setReplaceAll(true)
|
|
val emojiCompat = EmojiCompat.init(config)
|
|
|
|
EmojiManager.install(GoogleEmojiProvider())
|
|
|
|
NotificationUtils.registerNotificationChannels(applicationContext, appPreferences)
|
|
}
|
|
|
|
private fun initWorkers() {
|
|
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
|
|
val capabilitiesUpdateWork = OneTimeWorkRequest.Builder(CapabilitiesWorker::class.java).build()
|
|
val signalingSettingsWork = OneTimeWorkRequest.Builder(SignalingSettingsWorker::class.java).build()
|
|
val websocketConnectionsWorker = OneTimeWorkRequest.Builder(WebsocketConnectionsWorker::class.java).build()
|
|
|
|
WorkManager.getInstance(applicationContext)
|
|
.beginWith(accountRemovalWork)
|
|
.then(capabilitiesUpdateWork)
|
|
.then(signalingSettingsWork)
|
|
.then(websocketConnectionsWorker)
|
|
.enqueue()
|
|
|
|
val periodicCapabilitiesUpdateWork = PeriodicWorkRequest.Builder(
|
|
CapabilitiesWorker::class.java,
|
|
HALF_DAY,
|
|
TimeUnit.HOURS
|
|
).build()
|
|
WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
|
|
"DailyCapabilitiesUpdateWork",
|
|
ExistingPeriodicWorkPolicy.REPLACE,
|
|
periodicCapabilitiesUpdateWork
|
|
)
|
|
}
|
|
|
|
override fun onTerminate() {
|
|
super.onTerminate()
|
|
sharedApplication = null
|
|
}
|
|
//endregion
|
|
|
|
//region Protected methods
|
|
protected fun buildComponent() {
|
|
componentApplication = DaggerNextcloudTalkApplicationComponent.builder()
|
|
.busModule(BusModule())
|
|
.contextModule(ContextModule(applicationContext))
|
|
.databaseModule(DatabaseModule())
|
|
.restModule(RestModule(applicationContext))
|
|
.arbitraryStorageModule(ArbitraryStorageModule())
|
|
.build()
|
|
}
|
|
|
|
override fun attachBaseContext(base: Context) {
|
|
super.attachBaseContext(base)
|
|
MultiDex.install(this)
|
|
}
|
|
|
|
private fun buildDefaultImageLoader(): ImageLoader {
|
|
val imageLoaderBuilder = ImageLoader.Builder(applicationContext)
|
|
.memoryCache {
|
|
// Use 50% of the application's available memory.
|
|
MemoryCache.Builder(applicationContext).maxSizePercent(FIFTY_PERCENT).build()
|
|
}
|
|
.crossfade(true) // Show a short crossfade when loading images from network or disk into an ImageView.
|
|
.components {
|
|
if (SDK_INT >= P) {
|
|
add(ImageDecoderDecoder.Factory())
|
|
} else {
|
|
add(GifDecoder.Factory())
|
|
}
|
|
add(SvgDecoder.Factory())
|
|
}
|
|
|
|
if (BuildConfig.DEBUG) {
|
|
imageLoaderBuilder.logger(DebugLogger())
|
|
}
|
|
|
|
imageLoaderBuilder.okHttpClient(okHttpClient)
|
|
|
|
return imageLoaderBuilder.build()
|
|
}
|
|
|
|
companion object {
|
|
private val TAG = NextcloudTalkApplication::class.java.simpleName
|
|
const val FIFTY_PERCENT = 0.5
|
|
const val HALF_DAY: Long = 12
|
|
const val CIPHER_V4_MIGRATION: Int = 7
|
|
//region Singleton
|
|
//endregion
|
|
|
|
var sharedApplication: NextcloudTalkApplication? = null
|
|
protected set
|
|
//endregion
|
|
|
|
//region Setters
|
|
fun setAppTheme(theme: String) {
|
|
when (theme) {
|
|
"night_no" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
|
"night_yes" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
|
"battery_saver" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)
|
|
else ->
|
|
// will be "follow_system" only for now
|
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
|
}
|
|
}
|
|
}
|
|
//endregion
|
|
}
|