Skip to content
Snippets Groups Projects
Verified Commit 0f1aadc4 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Fixed debug builds not working on versions < 21

parent 22e586ae
No related branches found
No related tags found
No related merge requests found
Pipeline #396 passed
...@@ -57,8 +57,6 @@ android { ...@@ -57,8 +57,6 @@ android {
setProperty("archivesBaseName", "Quasseldroid-$versionName") setProperty("archivesBaseName", "Quasseldroid-$versionName")
multiDexEnabled = false
// Disable test runner analytics // Disable test runner analytics
testInstrumentationRunnerArguments = mapOf( testInstrumentationRunnerArguments = mapOf(
"disableAnalytics" to "true" "disableAnalytics" to "true"
...@@ -72,6 +70,8 @@ android { ...@@ -72,6 +70,8 @@ android {
isShrinkResources = true isShrinkResources = true
isUseProguard = false isUseProguard = false
multiDexEnabled = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android.txt"), getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro" "proguard-rules.pro"
...@@ -81,15 +81,7 @@ android { ...@@ -81,15 +81,7 @@ android {
getByName("debug") { getByName("debug") {
applicationIdSuffix = ".debug" applicationIdSuffix = ".debug"
isZipAlignEnabled = true multiDexEnabled = true
isMinifyEnabled = true
isShrinkResources = true
isUseProguard = false
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
} }
} }
...@@ -134,6 +126,8 @@ dependencies { ...@@ -134,6 +126,8 @@ dependencies {
implementation("androidx.paging", "paging-runtime", "2.0.0-rc01") implementation("androidx.paging", "paging-runtime", "2.0.0-rc01")
implementation("androidx.multidex", "multidex", "2.0.0")
// Utility // Utility
implementation("io.reactivex.rxjava2", "rxandroid", "2.0.2") implementation("io.reactivex.rxjava2", "rxandroid", "2.0.2")
implementation("io.reactivex.rxjava2", "rxjava", "2.1.9") implementation("io.reactivex.rxjava2", "rxjava", "2.1.9")
......
...@@ -20,224 +20,27 @@ ...@@ -20,224 +20,27 @@
package de.kuschku.quasseldroid package de.kuschku.quasseldroid
import android.content.Context import android.content.Context
import android.os.Build
import android.os.StrictMode
import com.squareup.leakcanary.LeakCanary
import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication import dagger.android.support.DaggerApplication
import de.kuschku.malheur.CrashHandler import de.kuschku.quasseldroid.app.AppDelegate
import de.kuschku.quasseldroid.app.QuasseldroidReleaseDelegate
import de.kuschku.quasseldroid.dagger.DaggerAppComponent import de.kuschku.quasseldroid.dagger.DaggerAppComponent
import de.kuschku.quasseldroid.persistence.db.AccountDatabase
import de.kuschku.quasseldroid.persistence.db.LegacyAccountDatabase
import de.kuschku.quasseldroid.persistence.models.Account
import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.SettingsMigration
import de.kuschku.quasseldroid.settings.SettingsMigrationManager
import de.kuschku.quasseldroid.util.backport.AndroidThreeTenBackport
import de.kuschku.quasseldroid.util.compatibility.AndroidCompatibilityUtils
import de.kuschku.quasseldroid.util.compatibility.AndroidLoggingHandler
import de.kuschku.quasseldroid.util.compatibility.AndroidStreamChannelFactory
import de.kuschku.quasseldroid.util.ui.LocaleHelper import de.kuschku.quasseldroid.util.ui.LocaleHelper
open class Quasseldroid : DaggerApplication() { open class Quasseldroid : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<Quasseldroid> = override fun applicationInjector() = DaggerAppComponent.builder().create(this)
DaggerAppComponent.builder().create(this) open val delegate: AppDelegate = QuasseldroidReleaseDelegate(this)
protected open fun init() {
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return
}
LeakCanary.install(this)
// Normal app init code...
CrashHandler.init(
application = this,
buildConfig = BuildConfig::class.java
)
// Init compatibility utils
AndroidCompatibilityUtils.inject()
AndroidLoggingHandler.inject()
AndroidStreamChannelFactory.inject()
AndroidThreeTenBackport.init(this)
applicationInjector().inject(this)
// Migrate preferences
SettingsMigrationManager(
listOf(
SettingsMigration.migrationOf(0, 1) { prefs, edit ->
// Migrating database
val database = LegacyAccountDatabase.Creator.init(this)
val accounts = database.accounts().all()
database.close()
val accountDatabase = AccountDatabase.Creator.init(this)
accountDatabase.accounts().create(*accounts.map {
Account(
id = it.id,
host = it.host,
port = it.port,
user = it.user,
requireSsl = false,
pass = it.pass,
name = it.name,
lastUsed = 0,
acceptedMissingFeatures = false,
defaultFiltered = 0
)
}.toTypedArray())
Thread(Runnable {
deleteDatabase("data")
}).start()
// Migrating actual settings
if (prefs.contains("selectedtheme")) {
prefs.getString("selectedtheme", "").let { theme ->
when (theme) {
"light" -> AppearanceSettings.Theme.MATERIAL_LIGHT
"dark" -> AppearanceSettings.Theme.MATERIAL_DARK
else -> null
}?.let {
edit.putString(getString(R.string.preference_theme_key), it.name)
}
}
edit.remove("selectedtheme")
}
if (prefs.contains("timestamp")) {
prefs.getString("timestamp", "").let {
val timestamp = it ?: ""
edit.putBoolean(getString(R.string.preference_show_seconds_key),
timestamp.contains("ss"))
edit.putBoolean(getString(R.string.preference_show_seconds_key),
!timestamp.contains("hh") && !timestamp.contains("a"))
}
edit.remove("timestamp")
}
if (prefs.contains("fontsizeChannelList")) {
prefs.getString("fontsizeChannelList", "")?.toIntOrNull()?.let { fontSize ->
edit.putInt(getString(R.string.preference_textsize_key), fontSize)
}
edit.remove("fontsizeChannelList")
}
if (prefs.contains("allowcoloredtext")) {
prefs.getBoolean("allowcoloredtext", false).let {
edit.putBoolean(getString(R.string.preference_colorize_mirc_key), it)
}
edit.remove("allowcoloredtext")
}
if (prefs.contains("monospace")) {
prefs.getBoolean("monospace", false).let {
edit.putBoolean(getString(R.string.preference_monospace_key), it)
}
edit.remove("monospace")
}
if (prefs.contains("detailed_actions")) {
prefs.getBoolean("detailed_actions", false).let {
edit.putBoolean(getString(R.string.preference_hostmask_actions_key), it)
}
edit.remove("detailed_actions")
}
if (prefs.contains("showlag")) {
prefs.getBoolean("showlag", false).let {
edit.putBoolean(getString(R.string.preference_show_lag_key), it)
}
edit.remove("showlag")
}
}
)
).migrate(this)
// Initialize preferences unless already set
/*
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
systemService<ShortcutManager>().dynamicShortcuts = listOf(
ShortcutInfo.Builder(this, "id1")
.setShortLabel("#quassel")
.setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
.setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
.build(),
ShortcutInfo.Builder(this, "id2")
.setShortLabel("#quasseldroid")
.setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
.setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
.build(),
ShortcutInfo.Builder(this, "id3")
.setShortLabel("#quassel.de")
.setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
.setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
.build(),
ShortcutInfo.Builder(this, "id4")
.setShortLabel("justJanne")
.setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_query))
.setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
.build()
)
}
*/
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectNetwork()
.detectCustomSlowCalls()
.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
it.detectResourceMismatches()
} else {
it
}
}.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.detectUnbufferedIo()
} else {
it
}
}
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedRegistrationObjects()
.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
it.detectFileUriExposure()
} else {
it
}
}.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.detectContentUriWithoutPermission()
} else {
it
}
}
.penaltyLog()
.build()
)
}
}
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
init() if (delegate.shouldInit()) {
delegate.onInit()
applicationInjector().inject(this)
delegate.onPostInit()
}
} }
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(LocaleHelper.setLocale(base)) super.attachBaseContext(LocaleHelper.setLocale(base))
delegate.onInstallMultidex()
} }
} }
/*
* Quasseldroid - Quassel client for Android
*
* Copyright (c) 2019 Janne Koschinski
* Copyright (c) 2019 The Quassel Project
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.kuschku.quasseldroid.app
interface AppDelegate {
fun shouldInit(): Boolean
fun onInstallMultidex()
fun onInit()
fun onPostInit()
}
/*
* Quasseldroid - Quassel client for Android
*
* Copyright (c) 2019 Janne Koschinski
* Copyright (c) 2019 The Quassel Project
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.kuschku.quasseldroid.app
import android.os.Build
import android.os.StrictMode
import androidx.multidex.MultiDex
import com.squareup.leakcanary.LeakCanary
import de.kuschku.malheur.CrashHandler
import de.kuschku.quasseldroid.BuildConfig
import de.kuschku.quasseldroid.Quasseldroid
import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.persistence.db.AccountDatabase
import de.kuschku.quasseldroid.persistence.db.LegacyAccountDatabase
import de.kuschku.quasseldroid.persistence.models.Account
import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.SettingsMigration
import de.kuschku.quasseldroid.settings.SettingsMigrationManager
import de.kuschku.quasseldroid.util.backport.AndroidThreeTenBackport
import de.kuschku.quasseldroid.util.compatibility.AndroidCompatibilityUtils
import de.kuschku.quasseldroid.util.compatibility.AndroidLoggingHandler
import de.kuschku.quasseldroid.util.compatibility.AndroidStreamChannelFactory
class QuasseldroidReleaseDelegate(private val app: Quasseldroid) :
AppDelegate {
override fun shouldInit() = !LeakCanary.isInAnalyzerProcess(app)
override fun onInit() {
LeakCanary.install(app)
// Normal app init code...
CrashHandler.init(
application = app,
buildConfig = BuildConfig::class.java
)
// Init compatibility utils
AndroidCompatibilityUtils.inject()
AndroidLoggingHandler.inject()
AndroidStreamChannelFactory.inject()
AndroidThreeTenBackport.init(app)
}
override fun onPostInit() {
// Migrate preferences
SettingsMigrationManager(
listOf(
SettingsMigration.migrationOf(0,
1) { prefs, edit ->
// Migrating database
val database = LegacyAccountDatabase.Creator.init(
app)
val accounts = database.accounts().all()
database.close()
val accountDatabase = AccountDatabase.Creator.init(
app)
accountDatabase.accounts().create(*accounts.map {
Account(
id = it.id,
host = it.host,
port = it.port,
user = it.user,
requireSsl = false,
pass = it.pass,
name = it.name,
lastUsed = 0,
acceptedMissingFeatures = false,
defaultFiltered = 0
)
}.toTypedArray())
Thread(Runnable {
app.deleteDatabase("data")
}).start()
// Migrating actual settings
if (prefs.contains("selectedtheme")) {
prefs.getString("selectedtheme", "").let { theme ->
when (theme) {
"light" -> AppearanceSettings.Theme.MATERIAL_LIGHT
"dark" -> AppearanceSettings.Theme.MATERIAL_DARK
else -> null
}?.let {
edit.putString(app.getString(R.string.preference_theme_key),
it.name)
}
}
edit.remove("selectedtheme")
}
if (prefs.contains("timestamp")) {
prefs.getString("timestamp", "").let {
val timestamp = it ?: ""
edit.putBoolean(app.getString(R.string.preference_show_seconds_key),
timestamp.contains("ss"))
edit.putBoolean(app.getString(R.string.preference_show_seconds_key),
!timestamp.contains("hh") && !timestamp.contains("a"))
}
edit.remove("timestamp")
}
if (prefs.contains("fontsizeChannelList")) {
prefs.getString("fontsizeChannelList", "")?.toIntOrNull()?.let { fontSize ->
edit.putInt(app.getString(R.string.preference_textsize_key),
fontSize)
}
edit.remove("fontsizeChannelList")
}
if (prefs.contains("allowcoloredtext")) {
prefs.getBoolean("allowcoloredtext", false).let {
edit.putBoolean(app.getString(R.string.preference_colorize_mirc_key),
it)
}
edit.remove("allowcoloredtext")
}
if (prefs.contains("monospace")) {
prefs.getBoolean("monospace", false).let {
edit.putBoolean(app.getString(R.string.preference_monospace_key),
it)
}
edit.remove("monospace")
}
if (prefs.contains("detailed_actions")) {
prefs.getBoolean("detailed_actions", false).let {
edit.putBoolean(app.getString(R.string.preference_hostmask_actions_key),
it)
}
edit.remove("detailed_actions")
}
if (prefs.contains("showlag")) {
prefs.getBoolean("showlag", false).let {
edit.putBoolean(app.getString(R.string.preference_show_lag_key),
it)
}
edit.remove("showlag")
}
}
)
).migrate(app)
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectNetwork()
.detectCustomSlowCalls()
.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
it.detectResourceMismatches()
} else {
it
}
}.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.detectUnbufferedIo()
} else {
it
}
}
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedRegistrationObjects()
.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
it.detectFileUriExposure()
} else {
it
}
}.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.detectContentUriWithoutPermission()
} else {
it
}
}
.penaltyLog()
.build()
)
}
}
override fun onInstallMultidex() {
if (BuildConfig.DEBUG) {
MultiDex.install(app)
}
}
}
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
package de.kuschku.quasseldroid package de.kuschku.quasseldroid
import de.kuschku.quasseldroid.app.QuasseldroidTestDelegate
class QuasseldroidTest : Quasseldroid() { class QuasseldroidTest : Quasseldroid() {
override fun init() { override val delegate = QuasseldroidTestDelegate()
applicationInjector().inject(this)
}
} }
/*
* Quasseldroid - Quassel client for Android
*
* Copyright (c) 2019 Janne Koschinski
* Copyright (c) 2019 The Quassel Project
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.kuschku.quasseldroid.app
class QuasseldroidTestDelegate : AppDelegate {
override fun shouldInit() = true
override fun onInstallMultidex() = Unit
override fun onInit() = Unit
override fun onPostInit() = Unit
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment