Compare commits

..

7 Commits

Author SHA1 Message Date
Arnau Mora
6d478deefc Merge branch 'main-ose' into 1737-enable-push-by-default 2026-02-02 09:29:02 +00:00
Arnau Mora
0362c72a11 Merge branch 'main-ose' into 1737-enable-push-by-default 2026-01-29 12:01:12 +00:00
Arnau Mora Gras
7cd161f89d Create PushDistributorManager
Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
2026-01-29 09:37:26 +01:00
Arnau Mora Gras
e61d4b9006 Optimize imports
Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
2026-01-29 09:27:01 +01:00
Arnau Mora Gras
5b58facb41 Merge branch 'main-ose' into 1737-enable-push-by-default
# Conflicts:
#	app/src/ose/kotlin/at/bitfire/davdroid/di/OseFlavorModule.kt
2026-01-29 09:25:41 +01:00
Arnau Mora
425478baa8 Merge branch 'main-ose' into 1737-enable-push-by-default 2025-12-18 09:42:24 +00:00
Arnau Mora
6e0cde71aa Added automatic push distributor selection 2025-12-11 15:33:06 +01:00
548 changed files with 682 additions and 1175 deletions

View File

@@ -49,10 +49,10 @@ jobs:
# Cache configurations for the other jobs (including assemble for CodeQL)
- name: Populate configuration cache
run: |
./gradlew --dry-run core:assembleDebug app:assembleDebug
./gradlew --dry-run core:lintDebug app:lintOseDebug
./gradlew --dry-run core:testDebugUnitTest
./gradlew --dry-run core:virtualDebugAndroidTest
./gradlew --dry-run app:assembleDebug
./gradlew --dry-run app:lintOseDebug
./gradlew --dry-run app:testOseDebugUnitTest
./gradlew --dry-run app:virtualOseDebugAndroidTest
unit_tests:
needs: compile
@@ -76,10 +76,10 @@ jobs:
key: android-${{ hashFiles('app/build.gradle.kts') }}
- name: Lint checks
run: ./gradlew core:lintDebug app:lintOseDebug
run: ./gradlew app:lintOseDebug
- name: Unit tests
run: ./gradlew core:testDebugUnitTest
run: ./gradlew app:testOseDebugUnitTest
instrumented_tests:
needs: compile
@@ -126,7 +126,7 @@ jobs:
sudo udevadm trigger --name-match=kvm
- name: Instrumented tests
run: ./gradlew core:virtualDebugAndroidTest
run: ./gradlew app:virtualOseDebugAndroidTest
- name: Cache AVD
uses: actions/cache/save@v5

View File

@@ -1,126 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
}
android {
compileSdk = 36
defaultConfig {
minSdk = 24 // Android 7.0
targetSdk = 36 // Android 16
applicationId = "at.bitfire.davdroid"
versionCode = 405090005
versionName = "4.5.9"
base.archivesName = "davx5-$versionCode-$versionName"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
buildFeatures {
compose = true
}
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "com.davx5.ose"
flavorDimensions += "distribution"
productFlavors {
create("ose") {
dimension = "distribution"
versionNameSuffix = "-ose"
}
}
androidResources {
generateLocaleConfig = true
}
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
isShrinkResources = true
signingConfig = signingConfigs.findByName("bitfire")
}
}
signingConfigs {
create("bitfire") {
storeFile = file(System.getenv("ANDROID_KEYSTORE") ?: "/dev/null")
storePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
}
}
@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
localDevices {
create("virtual") {
device = "Pixel 3"
// TBD: API level 35 and higher causes network tests to fail sometimes, see https://github.com/bitfireAT/davx5-ose/issues/1525
// Suspected reason: https://developer.android.com/about/versions/15/behavior-changes-all#background-network-access
apiLevel = 34
systemImageSource = "aosp-atd"
}
}
}
}
}
dependencies {
// include core subproject (manages its own dependencies itself, however from same version catalog)
implementation(project(":core"))
// Kotlin / Android
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
coreLibraryDesugaring(libs.android.desugaring)
// Hilt
implementation(libs.hilt.android.base)
ksp(libs.androidx.hilt.compiler)
ksp(libs.hilt.android.compiler)
// support libs
implementation(libs.androidx.core)
implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.viewmodel.base)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.work.base)
// Jetpack Compose
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.material3)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui.toolingPreview)
// own libraries
implementation(libs.bitfire.cert4android)
// third-party libs
implementation(libs.guava)
implementation(libs.okhttp.base)
implementation(libs.openid.appauth)
}

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
<application android:name=".App">
<!-- Required for Hilt/WorkManager integration. See
- https://developer.android.com/develop/background-work/background-tasks/persistent/configuration/custom-configuration#remove-default
- https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
However, we must not disable AndroidX startup completely, as it's needed by other libraries like okhttp. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
</application>
</manifest>

View File

@@ -1,30 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose
import androidx.work.Configuration
import at.bitfire.davdroid.CoreApp
import dagger.hilt.android.HiltAndroidApp
/**
* Actual implementation of Application, used for Hilt. Delegates to [CoreApp].
*/
@HiltAndroidApp
class App: CoreApp(), Configuration.Provider {
/**
* Required for Hilt/WorkManager integration, see:
* https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
*
* This requires to remove the androidx.work.WorkManagerInitializer from App Startup
* in the AndroidManifest, see:
* https://developer.android.com/develop/background-work/background-tasks/persistent/configuration/custom-configuration#remove-default
*/
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.AccountsDrawerHandler
import at.bitfire.davdroid.ui.OseAccountsDrawerHandler
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
@Module
@InstallIn(ActivityComponent::class)
interface AccountsDrawerHandlerModule {
@Binds
fun accountsDrawerHandler(impl: OseAccountsDrawerHandler): AccountsDrawerHandler
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.about.AboutActivity
import com.davx5.ose.ui.about.OpenSourceLicenseInfoProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
@Module
@InstallIn(ViewModelComponent::class)
interface AppLicenseInfoProviderModule {
@Binds
fun appLicenseInfoProvider(impl: OpenSourceLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import androidx.compose.material3.ColorScheme
import at.bitfire.davdroid.di.qualifier.DarkColorScheme
import at.bitfire.davdroid.di.qualifier.LightColorScheme
import at.bitfire.davdroid.ui.OseTheme
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class ColorSchemesModule {
@Provides
@LightColorScheme
fun lightColorScheme(): ColorScheme = OseTheme.lightScheme
@Provides
@DarkColorScheme
fun darkColorScheme(): ColorScheme = OseTheme.darkScheme
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.intro.IntroPageFactory
import com.davx5.ose.ui.intro.OseIntroPageFactory
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
interface Global {
@Binds
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory
}

View File

@@ -1,21 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
interface LoginTypesProviderModule {
@Binds
fun loginTypesProvider(impl: StandardLoginTypesProvider): LoginTypesProvider
}

View File

View File

@@ -3,7 +3,7 @@
*/
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.android.application)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.serialization)
@@ -16,7 +16,18 @@ android {
compileSdk = 36
defaultConfig {
applicationId = "at.bitfire.davdroid"
versionCode = 405090002
versionName = "4.5.9-rc.1"
base.archivesName = "davx5-ose-$versionName"
minSdk = 24 // Android 7.0
targetSdk = 36 // Android 16
// whether the build supports and allows to use custom certificates
buildConfigField("boolean", "allowCustomCerts", "true")
testInstrumentationRunner = "at.bitfire.davdroid.HiltTestRunner"
}
@@ -42,9 +53,37 @@ android {
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "at.bitfire.davdroid"
flavorDimensions += "distribution"
productFlavors {
create("ose") {
dimension = "distribution"
versionNameSuffix = "-ose"
}
}
sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
}
}
signingConfigs {
create("bitfire") {
storeFile = file(System.getenv("ANDROID_KEYSTORE") ?: "/dev/null")
storePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
isShrinkResources = true
signingConfig = signingConfigs.findByName("bitfire")
}
}
@@ -52,6 +91,10 @@ android {
disable += arrayOf("GoogleAppIndexingWarning", "ImpliedQuantity", "MissingQuantity", "MissingTranslation", "ExtraTranslation", "RtlEnabled", "RtlHardcoded", "Typos")
}
androidResources {
generateLocaleConfig = true
}
packaging {
resources {
// multiple (test) dependencies have LICENSE files at same location
@@ -59,12 +102,6 @@ android {
}
}
sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
}
}
@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
@@ -93,7 +130,7 @@ aboutLibraries {
}
dependencies {
// Kotlin / Android
// core
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
coreLibraryDesugaring(libs.android.desugaring)
@@ -130,7 +167,7 @@ dependencies {
// Glance Widgets
implementation(libs.androidx.glance.base)
implementation(libs.androidx.glance.material3)
implementation(libs.androidx.glance.material)
// Jetpack Room
implementation(libs.androidx.room.runtime)

View File

1
app/src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
espressoTest

View File

@@ -10,6 +10,7 @@ import android.os.Build
import android.os.Bundle
import androidx.test.runner.AndroidJUnitRunner
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule
import at.bitfire.davdroid.test.BuildConfig
import at.bitfire.synctools.log.LogcatHandler
import dagger.hilt.android.testing.HiltTestApplication
import java.util.logging.Level
@@ -28,7 +29,7 @@ class HiltTestRunner : AndroidJUnitRunner() {
val rootLogger = Logger.getLogger("")
rootLogger.level = Level.ALL
rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
rootLogger.addHandler(LogcatHandler(javaClass.name))
rootLogger.addHandler(LogcatHandler(BuildConfig.APPLICATION_ID))
// MockK requirements
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)

View File

@@ -5,10 +5,6 @@
package at.bitfire.davdroid.di
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule.standardTestDispatcher
import at.bitfire.davdroid.di.qualifier.DefaultDispatcher
import at.bitfire.davdroid.di.qualifier.IoDispatcher
import at.bitfire.davdroid.di.qualifier.MainDispatcher
import at.bitfire.davdroid.di.qualifier.SyncDispatcher
import dagger.Module
import dagger.Provides
import dagger.hilt.components.SingletonComponent

View File

@@ -11,7 +11,7 @@ import at.bitfire.dav4jvm.okhttp.Response
import at.bitfire.dav4jvm.property.caldav.CalDAV
import at.bitfire.dav4jvm.property.caldav.GetCTag
import at.bitfire.davdroid.db.Collection
import at.bitfire.davdroid.di.qualifier.SyncDispatcher
import at.bitfire.davdroid.di.SyncDispatcher
import at.bitfire.davdroid.resource.LocalResource
import at.bitfire.davdroid.resource.SyncState
import at.bitfire.davdroid.util.DavUtils.lastSegment

View File

@@ -5,7 +5,7 @@
package at.bitfire.davdroid.ui
import android.content.Context
import at.bitfire.davdroid.di.qualifier.IoDispatcher
import at.bitfire.davdroid.di.IoDispatcher
import at.bitfire.davdroid.ui.about.AboutModel
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Some files were not shown because too many files have changed in this diff Show More