mirror of
https://github.com/bitfireAT/davx5-ose.git
synced 2026-02-18 23:34:46 -05:00
Compare commits
34 Commits
1737-enabl
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2d5f8b7ac | ||
|
|
f183676fc2 | ||
|
|
8838db25c5 | ||
|
|
515360876e | ||
|
|
78bf028938 | ||
|
|
24de99a4fa | ||
|
|
6518ad2066 | ||
|
|
795616a613 | ||
|
|
2799bf33f7 | ||
|
|
ff3780ee01 | ||
|
|
63422b6e0e | ||
|
|
ba2cc5c46b | ||
|
|
7e7e56e35c | ||
|
|
1b8f215ffc | ||
|
|
e796448bad | ||
|
|
bb6be3c9cc | ||
|
|
a436e8181a | ||
|
|
ea81b929ca | ||
|
|
55202dff87 | ||
|
|
fb2c8cdd68 | ||
|
|
a9b24e5c45 | ||
|
|
a55ce927f7 | ||
|
|
7861cffa2e | ||
|
|
eab054d1c3 | ||
|
|
5e84648fb4 | ||
|
|
490abcb88a | ||
|
|
cca12e79d8 | ||
|
|
915cf73027 | ||
|
|
53773eaf83 | ||
|
|
9cd685982d | ||
|
|
d4902e84ce | ||
|
|
ec485fcfa5 | ||
|
|
5709aaa2e5 | ||
|
|
a19c397ef6 |
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -3,6 +3,3 @@
|
||||
|
||||
# Dependabot
|
||||
gradle/** @bitfireAT/app-dev
|
||||
|
||||
# everything else
|
||||
* @rfc2822
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/qualified-bug.yml
vendored
2
.github/ISSUE_TEMPLATE/qualified-bug.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Qualified Bug Report
|
||||
description: "For qualified bug reports. (Use Discussions if unsure.)"
|
||||
type: bug
|
||||
labels: ["bug"]
|
||||
labels: ["needs-triage"]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/qualified-feature.yml
vendored
2
.github/ISSUE_TEMPLATE/qualified-feature.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Qualified Feature Request
|
||||
description: "For qualified feature requests. (Use Discussions if unsure.)"
|
||||
type: feature
|
||||
labels: ["enhancement"]
|
||||
labels: ["needs-triage"]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
||||
50
.github/workflows/codeql.yml
vendored
50
.github/workflows/codeql.yml
vendored
@@ -1,50 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main-ose ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main-ose ]
|
||||
schedule:
|
||||
- cron: '22 10 * * 1'
|
||||
|
||||
concurrency:
|
||||
group: codeql-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
- uses: gradle/actions/setup-gradle@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
cache-read-only: true # gradle user home cache is generated by test jobs
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: java-kotlin
|
||||
build-mode: manual # autobuild uses older JDK
|
||||
|
||||
- name: Build # we must not use build cache here
|
||||
run: ./gradlew --no-daemon --configuration-cache app:assembleDebug
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
24
.github/workflows/dependency-submission.yml
vendored
24
.github/workflows/dependency-submission.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Dependency Submission
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'main-ose' ]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
dependency-submission:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
|
||||
- name: Generate and submit dependency graph
|
||||
uses: gradle/actions/dependency-submission@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
dependency-graph-exclude-configurations: '.*[Tt]est.* .*[cC]heck.*'
|
||||
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -9,6 +9,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
java-version: 21
|
||||
prerelease: ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }}
|
||||
|
||||
jobs:
|
||||
@@ -23,15 +24,17 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
java-version: ${{ env.java-version }}
|
||||
- uses: gradle/actions/setup-gradle@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
|
||||
- name: Prepare keystore
|
||||
run: echo ${{ secrets.android_keystore_base64 }} | base64 -d >$GITHUB_WORKSPACE/keystore.jks
|
||||
|
||||
- name: Build signed package
|
||||
# Use build cache to speed up building of build variants, but clean caches from previous tests before
|
||||
run: ./gradlew --build-cache --configuration-cache --no-daemon app:clean app:assembleRelease
|
||||
# don't use build cache to guarantee deterministic, fresh builds
|
||||
run: ./gradlew --no-build-cache --configuration-cache --no-daemon app:clean app-ose:assembleRelease
|
||||
env:
|
||||
ANDROID_KEYSTORE: ${{ github.workspace }}/keystore.jks
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.android_keystore_password }}
|
||||
@@ -42,6 +45,6 @@ jobs:
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
prerelease: ${{ env.prerelease }}
|
||||
files: app/build/outputs/apk/ose/release/*.apk
|
||||
files: app-ose/build/outputs/apk/ose/release/*.apk
|
||||
fail_on_unmatched_files: true
|
||||
generate_release_notes: true
|
||||
|
||||
55
.github/workflows/test-dev.yml
vendored
55
.github/workflows/test-dev.yml
vendored
@@ -2,7 +2,7 @@ name: Development tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main-ose'
|
||||
- 'main'
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
@@ -18,6 +18,7 @@ env:
|
||||
GRADLE_BUILDCACHE_USERNAME: ${{ secrets.gradle_buildcache_username }}
|
||||
GRADLE_BUILDCACHE_PASSWORD: ${{ secrets.gradle_buildcache_password }}
|
||||
GRADLE_OPTS: -Dorg.gradle.caching=true -Dorg.gradle.configuration-cache=true
|
||||
JAVA_VERSION: 21
|
||||
|
||||
jobs:
|
||||
compile:
|
||||
@@ -28,31 +29,17 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
# See https://community.gradle.org/github-actions/docs/setup-gradle/ for more information
|
||||
- uses: gradle/actions/setup-gradle@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
cache-read-only: false # allow branches to update their configuration cache
|
||||
cache-read-only: false # allow to update the cache
|
||||
gradle-home-cache-excludes: caches/build-cache-1 # don't cache local build cache because we use a remote cache
|
||||
|
||||
- name: Cache Android environment
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.config/.android # needs to be cached so that configuration cache can work
|
||||
key: android-${{ hashFiles('app/build.gradle.kts') }}
|
||||
|
||||
- name: Compile
|
||||
run: ./gradlew app:compileOseDebugSource
|
||||
|
||||
# Cache configurations for the other jobs (including assemble for CodeQL)
|
||||
- name: Populate configuration cache
|
||||
run: |
|
||||
./gradlew --dry-run app:assembleDebug
|
||||
./gradlew --dry-run app:lintOseDebug
|
||||
./gradlew --dry-run app:testOseDebugUnitTest
|
||||
./gradlew --dry-run app:virtualOseDebugAndroidTest
|
||||
run: ./gradlew app-ose:assembleDebug
|
||||
|
||||
unit_tests:
|
||||
needs: compile
|
||||
@@ -63,23 +50,18 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
- uses: gradle/actions/setup-gradle@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
cache-read-only: true
|
||||
|
||||
- name: Restore Android environment
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.config/.android
|
||||
key: android-${{ hashFiles('app/build.gradle.kts') }}
|
||||
|
||||
- name: Lint checks
|
||||
run: ./gradlew app:lintOseDebug
|
||||
run: ./gradlew core:lintDebug app:lintOseDebug
|
||||
|
||||
- name: Unit tests
|
||||
run: ./gradlew app:testOseDebugUnitTest
|
||||
# currently no unit tests for app-ose
|
||||
run: ./gradlew core:testDebugUnitTest
|
||||
|
||||
instrumented_tests:
|
||||
needs: compile
|
||||
@@ -90,18 +72,12 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
- uses: gradle/actions/setup-gradle@v5
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
|
||||
cache-read-only: true
|
||||
|
||||
- name: Restore Android environment
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.config/.android
|
||||
key: android-${{ hashFiles('app/build.gradle.kts') }}
|
||||
|
||||
# gradle and Android SDK often take more space than what is available on the default runner.
|
||||
# We try to free a few GB here to make gradle-managed devices more reliable.
|
||||
- name: Free some disk space
|
||||
@@ -115,8 +91,8 @@ jobs:
|
||||
id: restore-avd
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ~/.config/.android/avd # where AVD is stored
|
||||
key: avd-${{ hashFiles('app/build.gradle.kts') }} # gradle-managed devices are defined there
|
||||
path: ~/.config/.android/avd # where AVD is stored
|
||||
key: avd-${{ hashFiles('app-ose/build.gradle.kts') }} # gradle-managed devices are defined there
|
||||
|
||||
# Enable virtualization for Android emulator
|
||||
- name: Enable KVM group perms
|
||||
@@ -126,11 +102,12 @@ jobs:
|
||||
sudo udevadm trigger --name-match=kvm
|
||||
|
||||
- name: Instrumented tests
|
||||
run: ./gradlew app:virtualOseDebugAndroidTest
|
||||
# currently no instrumented tests for app-ose
|
||||
run: ./gradlew core:virtualDebugAndroidTest
|
||||
|
||||
- name: Cache AVD
|
||||
uses: actions/cache/save@v5
|
||||
if: steps.restore-avd.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ~/.config/.android/avd # where AVD is stored
|
||||
key: avd-${{ hashFiles('app/build.gradle.kts') }} # gradle-managed devices are defined there
|
||||
path: ~/.config/.android/avd # where AVD is stored
|
||||
key: avd-${{ hashFiles('app-ose/build.gradle.kts') }} # gradle-managed devices are defined there
|
||||
|
||||
130
app-ose/build.gradle.kts
Normal file
130
app-ose/build.gradle.kts
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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)
|
||||
alias(libs.plugins.mikepenz.aboutLibraries.android)
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24 // Android 7.0
|
||||
targetSdk = 36 // Android 16
|
||||
|
||||
applicationId = "at.bitfire.davdroid"
|
||||
|
||||
versionCode = 405100000
|
||||
versionName = "4.5.10-alpha.1"
|
||||
|
||||
base.archivesName = "davx5-$versionCode-$versionName"
|
||||
|
||||
// currently no instrumentation tests for app-ose, so no testInstrumentationRunner
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
|
||||
|
||||
isShrinkResources = true
|
||||
|
||||
// must be after signingConfigs {} block
|
||||
signingConfig = signingConfigs.findByName("bitfire")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
5
app-ose/proguard-rules-release.pro
Normal file
5
app-ose/proguard-rules-release.pro
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
-dontobfuscate
|
||||
-printusage build/reports/r8-usage.txt
|
||||
|
||||
# keep rules are taken from core/core-proguard-rules.pro
|
||||
29
app-ose/src/main/AndroidManifest.xml
Normal file
29
app-ose/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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>
|
||||
30
app-ose/src/main/kotlin/com/davx5/ose/App.kt
Normal file
30
app-ose/src/main/kotlin/com/davx5/ose/App.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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()
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************************************
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
**************************************************************************************************/
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid
|
||||
package com.davx5.ose
|
||||
|
||||
import android.content.Context
|
||||
import at.bitfire.davdroid.ui.DebugInfoActivity
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -2,63 +2,60 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
package com.davx5.ose.di
|
||||
|
||||
import android.content.Context
|
||||
import at.bitfire.cert4android.CustomCertManager
|
||||
import at.bitfire.cert4android.CustomCertStore
|
||||
import at.bitfire.cert4android.SettingsProvider
|
||||
import at.bitfire.davdroid.BuildConfig
|
||||
import at.bitfire.davdroid.settings.Settings
|
||||
import at.bitfire.davdroid.settings.SettingsManager
|
||||
import at.bitfire.davdroid.ui.ForegroundTracker
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.Reusable
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.internal.tls.OkHostnameVerifier
|
||||
import java.util.Optional
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
/**
|
||||
* cert4android integration module
|
||||
*/
|
||||
class CustomCertManagerModule {
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class Cert4AndroidModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun customCertStore(@ApplicationContext context: Context): Optional<CustomCertStore> =
|
||||
Optional.of(CustomCertStore.getInstance(context))
|
||||
|
||||
@Provides
|
||||
@Reusable
|
||||
fun customCertManager(
|
||||
@ApplicationContext context: Context,
|
||||
customCertStore: Optional<CustomCertStore>,
|
||||
settings: SettingsManager
|
||||
): Optional<CustomCertManager> =
|
||||
if (BuildConfig.allowCustomCerts)
|
||||
Optional.of(CustomCertManager(
|
||||
certStore = CustomCertStore.getInstance(context),
|
||||
settings = object : SettingsProvider {
|
||||
Optional.of(
|
||||
CustomCertManager(
|
||||
certStore = customCertStore.get(),
|
||||
settings = object : SettingsProvider {
|
||||
|
||||
override val appInForeground: Boolean
|
||||
get() = ForegroundTracker.inForeground.value
|
||||
override val appInForeground: Boolean
|
||||
get() = ForegroundTracker.inForeground.value
|
||||
|
||||
override val trustSystemCerts: Boolean
|
||||
get() = !settings.getBoolean(Settings.DISTRUST_SYSTEM_CERTIFICATES)
|
||||
override val trustSystemCerts: Boolean
|
||||
get() = !settings.getBoolean(Settings.DISTRUST_SYSTEM_CERTIFICATES)
|
||||
|
||||
}
|
||||
))
|
||||
else
|
||||
Optional.empty()
|
||||
}
|
||||
))
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Reusable
|
||||
fun customHostnameVerifier(
|
||||
customCertManager: Optional<CustomCertManager>
|
||||
): Optional<CustomCertManager.HostnameVerifier> =
|
||||
if (BuildConfig.allowCustomCerts && customCertManager.isPresent) {
|
||||
val hostnameVerifier = customCertManager.get().HostnameVerifier(OkHostnameVerifier)
|
||||
Optional.of(hostnameVerifier)
|
||||
} else
|
||||
Optional.empty()
|
||||
Optional.of(customCertManager.get().HostnameVerifier(OkHostnameVerifier))
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 IntroPageFactoryModule {
|
||||
@Binds
|
||||
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.about
|
||||
package com.davx5.ose.ui.about
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.text.Spanned
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -14,13 +14,16 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import at.bitfire.davdroid.di.qualifier.IoDispatcher
|
||||
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
|
||||
import at.bitfire.davdroid.ui.about.AboutActivity
|
||||
import com.google.common.io.CharStreams
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -40,13 +43,16 @@ class OpenSourceLicenseInfoProvider @Inject constructor(): AboutActivity.AppLice
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class Model @Inject constructor(app: Application): AndroidViewModel(app) {
|
||||
class Model @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
|
||||
): ViewModel() {
|
||||
|
||||
var gpl by mutableStateOf<Spanned?>(null)
|
||||
|
||||
init {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
app.resources.assets.open("gplv3.html").use { inputStream ->
|
||||
viewModelScope.launch(ioDispatcher) {
|
||||
context.resources.assets.open("gplv3.html").use { inputStream ->
|
||||
val raw = CharStreams.toString(inputStream.bufferedReader())
|
||||
gpl = HtmlCompat.fromHtml(raw, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
@@ -2,8 +2,15 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.intro
|
||||
package com.davx5.ose.ui.intro
|
||||
|
||||
import at.bitfire.davdroid.ui.intro.BackupsPage
|
||||
import at.bitfire.davdroid.ui.intro.BatteryOptimizationsPage
|
||||
import at.bitfire.davdroid.ui.intro.IntroPageFactory
|
||||
import at.bitfire.davdroid.ui.intro.OpenSourcePage
|
||||
import at.bitfire.davdroid.ui.intro.PermissionsIntroPage
|
||||
import at.bitfire.davdroid.ui.intro.TasksIntroPage
|
||||
import at.bitfire.davdroid.ui.intro.WelcomePage
|
||||
import javax.inject.Inject
|
||||
|
||||
class OseIntroPageFactory @Inject constructor(
|
||||
1
app/src/.gitignore
vendored
1
app/src/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
espressoTest
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
package at.bitfire.davdroid
|
||||
|
||||
import at.bitfire.synctools.icalendar.ical4jVersion
|
||||
import ezvcard.Ezvcard
|
||||
|
||||
/**
|
||||
* Brand-specific constants like (non-theme) colors, homepage URLs etc.
|
||||
*/
|
||||
object Constants {
|
||||
|
||||
const val DAVDROID_GREEN_RGBA = 0xFF8bc34a.toInt()
|
||||
|
||||
|
||||
// product IDs for iCalendar/vCard
|
||||
|
||||
val iCalProdId = "DAVx5/${BuildConfig.VERSION_NAME} ical4j/$ical4jVersion"
|
||||
const val vCardProdId = "+//IDN bitfire.at//DAVx5/${BuildConfig.VERSION_NAME} ez-vcard/${Ezvcard.VERSION}"
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.push
|
||||
|
||||
import android.content.Context
|
||||
import at.bitfire.davdroid.push.PushRegistrationManager.DistributorPreferences
|
||||
import at.bitfire.davdroid.settings.Settings.EXPLICIT_PUSH_DISABLE
|
||||
import at.bitfire.davdroid.settings.SettingsManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.unifiedpush.android.connector.UnifiedPush
|
||||
import java.util.logging.Logger
|
||||
import javax.inject.Inject
|
||||
|
||||
class PushDistributorManager @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val logger: Logger,
|
||||
private val settings: SettingsManager,
|
||||
private val distributorPreferences: DistributorPreferences,
|
||||
) {
|
||||
/**
|
||||
* Get the distributor registered by the user.
|
||||
* @return The distributor package name if any, else `null`.
|
||||
*/
|
||||
fun getCurrentDistributor() = UnifiedPush.getSavedDistributor(context)
|
||||
|
||||
/**
|
||||
* Get a list of available distributors installed on the system.
|
||||
* @return The list of distributor's package name.
|
||||
*/
|
||||
fun getDistributors() = UnifiedPush.getDistributors(context)
|
||||
|
||||
/**
|
||||
* Sets or removes (disable push) the distributor.
|
||||
*
|
||||
* @param pushDistributor new distributor or `null` to disable Push
|
||||
*/
|
||||
fun setPushDistributor(pushDistributor: String?) {
|
||||
// Disable UnifiedPush and remove all subscriptions
|
||||
UnifiedPush.removeDistributor(context)
|
||||
update()
|
||||
|
||||
if (pushDistributor != null) {
|
||||
// If a distributor was passed, store it and create/register subscriptions
|
||||
UnifiedPush.saveDistributor(context, pushDistributor)
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a distributor is selected if Push is enabled.
|
||||
*
|
||||
* Uses preferences from [distributorPreferences].
|
||||
*/
|
||||
fun update() {
|
||||
val currentDistributor = getCurrentDistributor()
|
||||
val isPushDisabled = settings.getBooleanOrNull(EXPLICIT_PUSH_DISABLE)
|
||||
if (currentDistributor == null) {
|
||||
if (isPushDisabled == true) {
|
||||
logger.info("Push is explicitly disabled, no distributor will be selected.")
|
||||
} else {
|
||||
val availableDistributors = getDistributors()
|
||||
if (availableDistributors.isNotEmpty()) {
|
||||
logger.fine("No Push distributor selected, but ${availableDistributors.size} distributors are available.")
|
||||
// select preferred distributor if available, otherwise first available
|
||||
val distributor = distributorPreferences.packageNames.firstNotNullOfOrNull { preferredPackageName ->
|
||||
availableDistributors.find { it == preferredPackageName }
|
||||
} ?: availableDistributors.first()
|
||||
logger.fine("Automatically selecting Push distributor: $distributor")
|
||||
UnifiedPush.saveDistributor(context, distributor)
|
||||
} else {
|
||||
logger.fine("No Push distributor selected and no distributors are available.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.composable
|
||||
|
||||
import android.content.Intent
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import io.ktor.http.HttpHeaders
|
||||
|
||||
@Composable
|
||||
fun WebViewCompat(
|
||||
url: String,
|
||||
modifier: Modifier = Modifier,
|
||||
layoutParams: ViewGroup.LayoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
) {
|
||||
AndroidView(
|
||||
modifier = modifier,
|
||||
factory = { context ->
|
||||
WebView(context).apply {
|
||||
this.layoutParams = layoutParams
|
||||
webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
||||
val intent = Intent(Intent.ACTION_VIEW, request.url)
|
||||
context.startActivity(intent)
|
||||
return true
|
||||
}
|
||||
}
|
||||
loadUrl(url, mapOf(
|
||||
HttpHeaders.AcceptLanguage to Locale.current.toLanguageTag()
|
||||
))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.widget
|
||||
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||
|
||||
class IconSyncButtonWidgetReceiver : GlanceAppWidgetReceiver() {
|
||||
override val glanceAppWidget: GlanceAppWidget = IconSyncButtonWidget()
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.widget
|
||||
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||
|
||||
class LabeledSyncButtonWidgetReceiver : GlanceAppWidgetReceiver() {
|
||||
override val glanceAppWidget: GlanceAppWidget = LabeledSyncButtonWidget()
|
||||
}
|
||||
@@ -1,483 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!--common strings-->
|
||||
<string name="account_invalid">Konto nicht (mehr) vorhanden</string>
|
||||
<string name="account_title_address_book">DAVx⁵-Adressbuch</string>
|
||||
<string name="account_prefs_use_app">Konto nicht hier ändern! Um Konten zu verwalten, stattdessen direkt die App nutzen.</string>
|
||||
<string name="dialog_delete">Löschen</string>
|
||||
<string name="dialog_remove">Entfernen</string>
|
||||
<string name="dialog_deny">Abbrechen</string>
|
||||
<string name="dialog_enable">Aktivieren</string>
|
||||
<string name="field_required">Feld wird benötigt</string>
|
||||
<string name="help">Hilfe</string>
|
||||
<string name="navigate_up">Aufwärts navigieren</string>
|
||||
<string name="options_menu">Auswahlmenü</string>
|
||||
<string name="share">Teilen</string>
|
||||
<string name="sync_started">Synchronisierung gestartet/eingereiht</string>
|
||||
<string name="database_destructive_migration_title">Datenbank beschädigt</string>
|
||||
<string name="database_destructive_migration_text">Alle Konten wurden lokal entfernt.</string>
|
||||
<string name="notification_channel_debugging">Fehlersuche</string>
|
||||
<string name="notification_channel_general">Andere wichtige Mitteilungen</string>
|
||||
<string name="notification_channel_status">Weniger wichtige Statusmitteilungen</string>
|
||||
<string name="notification_channel_sync">Synchronisierung</string>
|
||||
<string name="notification_channel_sync_errors">Synchronisierungsfehler</string>
|
||||
<string name="notification_channel_sync_errors_desc">Fehler, die zum Abbruch der Synchronisierung führen, wie z.B. unerwartete Serverantworten</string>
|
||||
<string name="notification_channel_sync_warnings">Synchronisierungswarnungen</string>
|
||||
<string name="notification_channel_sync_warnings_desc">Nicht fatale Synchronisierungsprobleme wie bestimmte ungültige Dateien</string>
|
||||
<string name="notification_channel_sync_io_errors">Netzwerk- und E/A-Fehler</string>
|
||||
<string name="notification_channel_sync_io_errors_desc">Zeitüberschreitungen, Verbindungsprobleme, usw. (oft vorübergehend)</string>
|
||||
<!--IntroActivity-->
|
||||
<string name="intro_slogan1">Dein Leben. Deine Daten.</string>
|
||||
<string name="intro_slogan2">Deine Entscheidung.</string>
|
||||
<string name="intro_battery_title">Regelmäßige Sync-Intervalle</string>
|
||||
<string name="intro_battery_text">Zur Synchronisierung in regelmäßigen Intervallen muss %s im Hintergrund laufen dürfen; ansonsten kann Android die Synchronisierung jederzeit aussetzen.</string>
|
||||
<string name="intro_battery_dont_show">Ich brauche keine regelmäßigen Sync-Intervalle.*</string>
|
||||
<string name="intro_autostart_title">%s-Kompatibilität</string>
|
||||
<string name="intro_autostart_text">Herstellerspezifische Firmware blockiert möglicherweise die Synchronisierung. Wenn Sie davon betroffen sind, können Sie dies nur manuell beheben.</string>
|
||||
<string name="intro_autostart_dont_show">Ich habe die Einstellungen gemacht, nicht mehr erinnern.*</string>
|
||||
<string name="intro_leave_unchecked">* Nicht anwählen, um später erinnert zu werden. Kann unter App-Einstellungen / %s zurückgesetzt werden.</string>
|
||||
<string name="intro_more_info">Mehr Infos</string>
|
||||
<string name="intro_tasks_jtx">jtx Board</string>
|
||||
<string name="intro_tasks_jtx_info"><![CDATA[Unterstützt Synchronisierung von Aufgaben, Journalen und Notizen.]]></string>
|
||||
<string name="intro_tasks_title">Unterstützung für Aufgaben</string>
|
||||
<string name="intro_tasks_text1">Falls der Server Aufgaben unterstützt, können sie mit einer unterstützten App synchronisiert werden:</string>
|
||||
<string name="intro_tasks_opentasks">OpenTasks</string>
|
||||
<string name="intro_tasks_opentasks_info">Wird anscheinend nicht weiterentwickelt – nicht empfohlen.</string>
|
||||
<string name="intro_tasks_tasks_org">Tasks.org</string>
|
||||
<string name="intro_tasks_tasks_org_info"><![CDATA[Einige Funktionen <a href="https://www.davx5.com/faq/tasks/advanced-task-features">werden nicht unterstützt</a>.]]></string>
|
||||
<string name="intro_tasks_no_app_store">Kein App-Store verfügbar</string>
|
||||
<string name="intro_tasks_dont_show">Ich brauche keine Unterstützung für Aufgaben.*</string>
|
||||
<string name="intro_open_source_title">Open-Source-Software</string>
|
||||
<string name="intro_open_source_text">Wir freuen uns, dass Sie die Open-Source-Software %s verwenden. Entwicklung, Wartung und Support sind viel Arbeit. Ziehen Sie daher bitte in Betracht, mitzuhelfen (dazu gibt es viele Möglichkeiten) oder zu spenden. Vielen Dank!</string>
|
||||
<string name="intro_open_source_details">Infos zum Mithelfen/Spenden</string>
|
||||
<string name="intro_open_source_dont_show">Nicht daran erinnern für</string>
|
||||
<plurals name="intro_open_source_dont_show_months">
|
||||
<item quantity="one">%d Monat</item>
|
||||
<item quantity="other">%d Monate</item>
|
||||
</plurals>
|
||||
<string name="intro_next">Weiter</string>
|
||||
<!--PermissionsActivity-->
|
||||
<string name="permissions_title">Berechtigungsverwaltung</string>
|
||||
<string name="permissions_text">%s benötigt Berechtigungen, um ordnungsgemäß zu funktionieren.</string>
|
||||
<string name="permissions_all_title">Alles darunter</string>
|
||||
<string name="permissions_all_status_off">Hiermit können alle Funktionen aktiviert werden (empfohlen)</string>
|
||||
<string name="permissions_all_status_on">Alle Berechtigungen gewährt</string>
|
||||
<string name="permissions_contacts_title">Kontakte-Berechtigungen</string>
|
||||
<string name="permissions_contacts_status_off">Keine Kontakte-Synchronisierung (nicht empfohlen)</string>
|
||||
<string name="permissions_contacts_status_on">Kontakte-Synchronisierung möglich</string>
|
||||
<string name="permissions_calendar_title">Kalender-Berechtigungen</string>
|
||||
<string name="permissions_calendar_status_off">Keine Kalender-Synchronisierung (nicht empfohlen)</string>
|
||||
<string name="permissions_calendar_status_on">Kalender-Synchronisierung möglich</string>
|
||||
<string name="permissions_notification_title">Benachrichtigungsberechtigung</string>
|
||||
<string name="permissions_notification_status_off">Benachrichtigungen deaktiviert (nicht empfohlen)</string>
|
||||
<string name="permissions_notification_status_on">Benachrichtigungen aktiviert</string>
|
||||
<string name="permissions_jtx_title">jtx Board-Berechtigungen</string>
|
||||
<string name="permissions_opentasks_title">OpenTasks-Berechtigungen</string>
|
||||
<string name="permissions_tasksorg_title">Tasks-Berechtigungen</string>
|
||||
<string name="permissions_tasks_status_off">Keine Aufgaben-Synchronisierung</string>
|
||||
<string name="permissions_tasks_status_on">Aufgaben-Synchronisierung möglich</string>
|
||||
<string name="permissions_autoreset_title">Berechtigungen behalten</string>
|
||||
<string name="permissions_autoreset_status_off">Berechtigungen können automatisch entzogen werden (nicht empfohlen)</string>
|
||||
<string name="permissions_autoreset_status_on">Berechtigungen werden nicht automatisch entzogen</string>
|
||||
<string name="permissions_autoreset_instruction">Berechtigungen > \"Berechtigungen entfernen, wenn die App nicht verwendet wird\" abwählen</string>
|
||||
<string name="permissions_app_settings_hint">Wenn ein Schalter nicht funktioniert, App-Einstellungen / Berechtigungen verwenden.</string>
|
||||
<string name="permissions_app_settings">App-Einstellungen</string>
|
||||
<!--WifiPermissionsActivity-->
|
||||
<string name="wifi_permissions_label">WLAN-SSID-Berechtigungen</string>
|
||||
<string name="wifi_permissions_intro">Um auf den aktuellen WLAN-Namen (SSID) zugreifen zu können, müssen folgende Bedingungen erfüllt werden:</string>
|
||||
<string name="wifi_permissions_location_permission">Exakter Standort-Berechtigung</string>
|
||||
<string name="wifi_permissions_location_permission_on">Standort-Zugriff erlaubt</string>
|
||||
<string name="wifi_permissions_location_permission_off">Standort-Zugriff verweigert</string>
|
||||
<string name="wifi_permissions_background_location_permission">Hintergrund-Standort-Berechtigung</string>
|
||||
<string name="wifi_permissions_background_location_permission_label">Immer zulassen</string>
|
||||
<string name="wifi_permissions_background_location_permission_on">Standort-Zugriff eingestellt auf: %s</string>
|
||||
<string name="wifi_permissions_background_location_permission_off">Standort-Zugriff nicht eingestellt auf: %s</string>
|
||||
<string name="wifi_permissions_background_location_disclaimer">%s benutzt Standortdaten (nur WLAN-SSID) ausschließlich, um die Synchronisierung auf ein bestimmtes WLAN zu beschränken. Dies geschieht auch dann, wenn die Synchronisierung im Hintergrund ausgeführt wird.</string>
|
||||
<string name="wifi_permissions_background_location_disclaimer2">Alle Standortdaten (nur WLAN-SSID) werden nur lokal verwendet und nicht an Dritte weitergegeben.</string>
|
||||
<string name="wifi_permissions_location_enabled">Standort-Dienst immer aktiviert</string>
|
||||
<string name="wifi_permissions_location_enabled_on">Standort-Dienst aktiv</string>
|
||||
<string name="wifi_permissions_location_enabled_off">Standort-Dienst inaktiv</string>
|
||||
<!--AboutActivity-->
|
||||
<string name="about_translations">Übersetzungen</string>
|
||||
<string name="about_libraries">Bibliotheken</string>
|
||||
<string name="about_version">Version %1$s (%2$d)</string>
|
||||
<string name="about_copyright">© Ricki Hirner, Bernhard Stockmann (bitfire web engineering GmbH) und Mitwirkende</string>
|
||||
<string name="about_license_info_no_warranty">Dieses Programm wird OHNE JEDE GEWÄHRLEISTUNG bereitgestellt. Es ist freie Software – Sie können es also unter bestimmten Bedingungen weiterverbreiten.</string>
|
||||
<!--global settings-->
|
||||
<string name="logging_couldnt_create_file">Protokolldatei konnte nicht angelegt werden</string>
|
||||
<string name="logging_notification_text">Alle %s-Aktivitäten werden protokolliert</string>
|
||||
<string name="logging_notification_view_share">Anzeigen/teilen</string>
|
||||
<string name="logging_notification_disable">Deaktivieren</string>
|
||||
<!--AccountsScreen-->
|
||||
<string name="navigation_drawer_subtitle">CalDAV/CardDAV-Sync-Adapter</string>
|
||||
<string name="navigation_drawer_about">Über / Lizenz</string>
|
||||
<string name="navigation_drawer_beta_feedback">Beta-Rückmeldung</string>
|
||||
<string name="install_browser">Bitte installieren Sie einen Web-Browser</string>
|
||||
<string name="navigation_drawer_settings">Einstellungen</string>
|
||||
<string name="navigation_drawer_news_updates">Aktuelles</string>
|
||||
<string name="navigation_drawer_tools">Werkzeuge</string>
|
||||
<string name="navigation_drawer_external_links">Externe Links</string>
|
||||
<string name="navigation_drawer_website">Homepage</string>
|
||||
<string name="navigation_drawer_manual">Handbuch</string>
|
||||
<string name="navigation_drawer_faq">FAQ</string>
|
||||
<string name="navigation_drawer_managed">Für Organisationen</string>
|
||||
<string name="navigation_drawer_community">Community</string>
|
||||
<string name="navigation_drawer_support_project">Projekt unterstützen</string>
|
||||
<string name="navigation_drawer_contribute">Einen Beitrag leisten</string>
|
||||
<string name="navigation_drawer_privacy_policy">Datenschutzerklärung</string>
|
||||
<string name="account_list_welcome">Willkommen bei DAVx⁵!</string>
|
||||
<string name="account_list_empty">Verbinden Sie sich mit Ihrem Server und synchronisieren Sie Ihre Kalender und Kontakte.</string>
|
||||
<string name="accounts_sync_all">Alle Konten synchronisieren</string>
|
||||
<!--Sync warnings-->
|
||||
<string name="sync_warning_no_notification_permission">Benachrichtigungen deaktiviert. Sie werden nicht über Fehler bei der Synchronisierung informiert.</string>
|
||||
<string name="sync_warning_no_internet">Automatische Synchronisation nicht aktiv (keine überprüfte Internetverbindung).</string>
|
||||
<string name="sync_warning_manage_connections">Verbindungen steuern</string>
|
||||
<string name="sync_warning_datasaver_enabled">Datensparen aktiviert. Hintergrundsynchronisierung ist eingeschränkt.</string>
|
||||
<string name="sync_warning_manage_datasaver">Datensparen verwalten</string>
|
||||
<string name="sync_warning_battery_saver_enabled">Energiesparmodus aktiviert. Synchronisierung kann eingeschränkt sein.</string>
|
||||
<string name="sync_warning_manage_battery_saver">Energieeinstellungen verwalten</string>
|
||||
<string name="sync_warning_low_storage">Wenig Speicherplatz. Android wird lokale Änderungen nicht sofort synchronisieren, sondern bei der nächsten regulären Synchronisierung.</string>
|
||||
<string name="sync_warning_manage_storage">Speicherplatz verwalten</string>
|
||||
<string name="sync_warning_calendar_storage_disabled_title">Kalender-Provider fehlt</string>
|
||||
<string name="sync_warning_calendar_storage_disabled_description">Haben Sie die »Kalender«-System-App deaktiviert?</string>
|
||||
<string name="sync_warning_contacts_storage_disabled_title">Kontakte-Provider fehlt</string>
|
||||
<string name="sync_warning_contacts_storage_disabled_description">Haben Sie die »Kontakte«-System-App deaktiviert?</string>
|
||||
<string name="sync_warning_manage_apps">Apps verwalten</string>
|
||||
<!--RefreshCollectionsWorker-->
|
||||
<string name="refresh_collections_worker_refresh_failed">Diensterkennung fehlgeschlagen</string>
|
||||
<string name="refresh_collections_worker_refresh_couldnt_refresh">Ordnerliste konnte nicht aktualisiert werden</string>
|
||||
<!--Foreground service used by WorkManager on Android <12-->
|
||||
<string name="foreground_service_notify_title">Läuft im Vordergrund</string>
|
||||
<string name="foreground_service_notify_text">Auf manchen Geräten für die automatische Synchronisierung benötigt</string>
|
||||
<!--AppSettingsActivity-->
|
||||
<string name="app_settings">Einstellungen</string>
|
||||
<string name="app_settings_debug">Fehlersuche</string>
|
||||
<string name="app_settings_show_debug_info">Informationen zur Fehlersuche</string>
|
||||
<string name="app_settings_show_debug_info_details">Einstellungsdetails und Logs anzeigen/teilen</string>
|
||||
<string name="app_settings_logging">Ausführliche Protokollierung</string>
|
||||
<string name="app_settings_logging_on">Logging ist aktiv. Sie können die Logs in den Debuginformationen anzeigen.</string>
|
||||
<string name="app_settings_logging_off">Keine Protokollierung</string>
|
||||
<string name="app_settings_battery_optimization">Akku-Optimierung</string>
|
||||
<string name="app_settings_battery_optimization_exempted">App ist ausgenommen (empfohlen)</string>
|
||||
<string name="app_settings_battery_optimization_optimized">Akku-Einschränkungen gelten (nicht empfohlen)</string>
|
||||
<string name="app_settings_connection">Verbindung</string>
|
||||
<string name="app_settings_proxy">Proxy-Typ</string>
|
||||
<string-array name="app_settings_proxy_types">
|
||||
<item>System-Standard</item>
|
||||
<item>Kein Proxy</item>
|
||||
<item>HTTP</item>
|
||||
<item>SOCKS (für Orbot)</item>
|
||||
</string-array>
|
||||
<string name="app_settings_proxy_host">Proxy-Rechnername</string>
|
||||
<string name="app_settings_proxy_port">Proxy-Port</string>
|
||||
<string name="app_settings_security">Sicherheit</string>
|
||||
<string name="app_settings_security_app_permissions">App-Berechtigungen</string>
|
||||
<string name="app_settings_security_app_permissions_summary">Für die Synchronisierung benötigte Berechtigungen prüfen</string>
|
||||
<string name="app_settings_distrust_system_certs">Systemzertifikaten nicht vertrauen</string>
|
||||
<string name="app_settings_distrust_system_certs_on">System- und installierten CAs wird nicht vertraut</string>
|
||||
<string name="app_settings_distrust_system_certs_off">System- und installierten CAs wird vertraut (empfohlen)</string>
|
||||
<string name="app_settings_distrust_system_certs_dialog_message">Wenn diese Einstellung aktiv ist, werden Systemzertifikate als nicht vertrauenswürdig erachtet. Das bedeutet, dass Sie jedes Zertifikat (auch wenn der Server sein Zertifikat auffrischt) von Hand akzeptieren müssen; sonst werden Kontoeinrichtung und Synchronisierung nicht funktionieren.</string>
|
||||
<string name="app_settings_reset_certificates">Zertifikat-Vertrauen zurücksetzen</string>
|
||||
<string name="app_settings_reset_certificates_summary">Setzt angenommene/abgelehnte Zertifikate zurück</string>
|
||||
<string name="app_settings_reset_certificates_success">Angenommene/abgelehnte Zertifikate zurückgesetzt</string>
|
||||
<string name="app_settings_user_interface">Oberfläche</string>
|
||||
<string name="app_settings_notification_settings">Benachrichtigungseinstellungen</string>
|
||||
<string name="app_settings_notification_settings_summary">Benachrichtigungskanäle und -einstellungen verwalten</string>
|
||||
<string name="app_settings_theme_title">Aussehen wählen</string>
|
||||
<string-array name="app_settings_theme_names">
|
||||
<item>wie System</item>
|
||||
<item>heller Stil</item>
|
||||
<item>dunkler Stil</item>
|
||||
</string-array>
|
||||
<string name="app_settings_reset_hints">Hinweise zurücksetzen</string>
|
||||
<string name="app_settings_reset_hints_summary">Hinweise, die deaktiviert wurden, wieder anzeigen</string>
|
||||
<string name="app_settings_reset_hints_success">Alle Hinweise werden wieder angezeigt</string>
|
||||
<string name="app_settings_integration">Integration</string>
|
||||
<string name="app_settings_tasks_provider">Aufgaben-App</string>
|
||||
<string name="app_settings_tasks_provider_none">Keine kompatible Aufgaben-App gefunden</string>
|
||||
<string name="app_settings_unifiedpush">UnifiedPush (experimentell)</string>
|
||||
<string name="app_settings_unifiedpush_disable">Keiner (Push deaktivieren)</string>
|
||||
<string name="app_settings_unifiedpush_choose_distributor">Anbieter auswählen</string>
|
||||
<string name="app_settings_unifiedpush_no_distributor">Kein Push-Anbieter installiert</string>
|
||||
<string name="app_settings_unifiedpush_no_endpoint">Kein Endpunkt konfiguriert</string>
|
||||
<string name="app_settings_unifiedpush_ready">Bereit, Push-Mitteilungen über %s zu empfangen</string>
|
||||
<string name="app_settings_unifiedpush_distributor_fcm">FCM (Google Play)</string>
|
||||
<string name="app_settings_unifiedpush_encrypted">Push-Nachrichten sind immer verschlüsselt.</string>
|
||||
<!--AccountScreen-->
|
||||
<string name="account_invalid_account">Konto wurde entfernt</string>
|
||||
<string name="account_carddav">CardDAV</string>
|
||||
<string name="account_caldav">CalDAV</string>
|
||||
<string name="account_webcal">Webcal</string>
|
||||
<string name="account_missing_permissions">Für die Synchronisierung dieser Ordner sind zusätzliche Berechtigungen erforderlich.</string>
|
||||
<string name="account_manage_permissions">Berechtigungen verwalten</string>
|
||||
<string name="account_synchronize_now">Jetzt synchronisieren</string>
|
||||
<string name="account_settings">Konto-Einstellungen</string>
|
||||
<string name="account_rename">Konto umbenennen</string>
|
||||
<string name="account_rename_new_name_description">Nicht gespeicherte lokale Daten können verloren gehen. Nach dem Umbenennen ist eine erneute Synchronisierung erforderlich.</string>
|
||||
<string name="account_rename_new_name">Neuer Kontoname</string>
|
||||
<string name="account_rename_rename">Umbenennen</string>
|
||||
<string name="account_rename_exists_already">Kontoname bereits verwendet</string>
|
||||
<string name="account_rename_couldnt_rename">Konto konnte nicht umbenannt werden</string>
|
||||
<string name="account_delete">Konto löschen</string>
|
||||
<string name="account_delete_confirmation_title">Konto wirklich löschen?</string>
|
||||
<string name="account_delete_confirmation_text">Alle Adressbücher, Kalender und Aufgabenlisten werden vom Gerät (nicht am Server) gelöscht.</string>
|
||||
<string name="account_synchronize_this_collection">Diesen Ordner synchronisieren</string>
|
||||
<string name="account_read_only">schreibgeschützt</string>
|
||||
<string name="account_calendar">Kalender</string>
|
||||
<string name="account_contacts">Kontakte</string>
|
||||
<string name="account_journal">Journal</string>
|
||||
<string name="account_task_list">Aufgaben</string>
|
||||
<string name="account_only_personal">Nur eigene anzeigen</string>
|
||||
<string name="account_refresh_collections">Liste aktualisieren</string>
|
||||
<string name="account_webcal_external_app">Webcal-Abonnements können mit externen Apps synchronisiert werden.</string>
|
||||
<string name="account_no_webcal_handler_found">Keine Webcal-App gefunden</string>
|
||||
<string name="account_install_icsx5">ICSx⁵ installieren</string>
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_title">Konto hinzufügen</string>
|
||||
<string name="login_privacy_hint"><![CDATA[Alle Daten werden nur zwischen Ihrem Server und Ihrem Gerät übertragen. %1$s wird sie nirgendwohin sonst schicken. Siehe die <a href="%2$s">Datenschutzbestimmungen</a>.]]></string>
|
||||
<string name="login_generic_login">Allgemeine Anmeldung</string>
|
||||
<string name="login_provider_login">Provider-spezifische Anmeldung</string>
|
||||
<string name="login_continue">Fortfahren</string>
|
||||
<string name="login_login">Anmelden</string>
|
||||
<string name="login_type_email">Mit E-Mail-Adresse anmelden</string>
|
||||
<string name="login_email_address">E-Mail-Adresse</string>
|
||||
<string name="login_email_address_error">Gültige E-Mail-Adresse benötigt</string>
|
||||
<string name="login_email_address_info"><![CDATA[Die E-Mail-Domäne wird als Basis-URL verwendet. <a href="%s">Dienst-Erkennung</a> erfolgt über DNS-Einträge und well-known-URLs.]]></string>
|
||||
<string name="login_password">Passwort</string>
|
||||
<string name="login_password_hide">Passwort ausblenden</string>
|
||||
<string name="login_password_show">Passwort anzeigen</string>
|
||||
<string name="login_password_optional">Passwort (optional)</string>
|
||||
<string name="login_type_url">Mit URL und Benutzername anmelden</string>
|
||||
<string name="login_user_name">Benutzername</string>
|
||||
<string name="login_user_name_optional">Benutzername (optional)</string>
|
||||
<string name="login_base_url">Basis-URL</string>
|
||||
<string name="login_base_url_info"><![CDATA[Basis-URL wird direkt geprüft, aber es erfolgt auch <a href="%s">Dienst-Erkennung</a> über DNS-Einträge und well-known-URLs.]]></string>
|
||||
<string name="login_select_certificate">Zertifikat auswählen</string>
|
||||
<string name="login_add_account">Konto hinzufügen</string>
|
||||
<string name="login_account_name">Kontoname</string>
|
||||
<string name="login_account_avoid_apostrophe">Das Verwenden von Apostrophen (\') scheint auf einigen Geräten Probleme zu verursachen.</string>
|
||||
<string name="login_account_name_info">Verwenden Sie Ihre E-Mail-Adresse als Kontonamen, da Android den Kontonamen als ORGANIZER einsetzt. Es kann allerdings keine zwei Konten mit dem gleichen Namen geben.</string>
|
||||
<string name="login_account_contact_group_method">Kontaktgruppen-Methode:</string>
|
||||
<string name="login_account_name_required">Kontoname wird benötigt</string>
|
||||
<string name="login_account_name_already_taken">Kontoname bereits verwendet</string>
|
||||
<string name="login_account_not_added">Konto konnte nicht hinzugefügt werden</string>
|
||||
<string name="login_finish">Abschließen</string>
|
||||
<string name="login_type_advanced">Erweiterte Anmeldung</string>
|
||||
<string name="login_no_client_certificate_optional">Kein Client-Zertifikat (optional)</string>
|
||||
<string name="login_client_certificate_selected">Client-Zertifikat: %s</string>
|
||||
<string name="login_no_certificate_found">Kein Zertifikat gefunden</string>
|
||||
<string name="login_install_certificate">Zertifikat installieren </string>
|
||||
<string name="login_fastmail">Fastmail</string>
|
||||
<string name="login_fastmail_account">Fastmail-Konto</string>
|
||||
<string name="login_fastmail_sign_in">Mit Fastmail anmelden</string>
|
||||
<string name="login_type_google">Google-Kontakte / -Kalender</string>
|
||||
<string name="login_google_account">Google-Konto</string>
|
||||
<string name="login_google">Mit Google anmelden</string>
|
||||
<string name="login_google_client_id">Client-ID (optional)</string>
|
||||
<string name="login_google_client_privacy_policy"><![CDATA[%1$s überträgt Ihre Google-Kontakte und -Kalenderdaten zur Synchronisierung mit diesem Gerät. Siehe auch unsere <a href="%2$s">Datenschutzrichtlinie</a> für mehr Informationen.]]></string>
|
||||
<string name="login_google_client_limited_use"><![CDATA[%1$s richtet sich nach der <a href="%2$s">Google API Services Nutzerdaten-Richtlinie</a>, inklusive der eingeschränkten Nutzungsbedingungen.]]></string>
|
||||
<string name="login_oauth_couldnt_obtain_auth_code">Authentifizierungscode konnte nicht abgerufen werden</string>
|
||||
<string name="login_type_nextcloud">Nextcloud</string>
|
||||
<string name="login_nextcloud_login_with_nextcloud">Mit Nextcloud anmelden</string>
|
||||
<string name="login_nextcloud_login_flow_text">Dadurch wird der Nextcloud-Anmeldevorgang in einem Webbrowser gestartet.</string>
|
||||
<string name="login_nextcloud_login_flow_server_address">Nextcloud-Serveradresse</string>
|
||||
<string name="login_nextcloud_login_flow_sign_in">Anmeldung</string>
|
||||
<string name="login_nextcloud_login_flow_no_login_url">Login-URL konnte nicht abgerufen werden</string>
|
||||
<string name="login_nextcloud_login_flow_no_login_data">Anmeldedaten konnten nicht abgerufen werden</string>
|
||||
<string name="login_configuration_detection">Ressourcen-Erkennung</string>
|
||||
<string name="login_querying_server">Server wird abgefragt. Bitte warten …</string>
|
||||
<string name="login_no_service">Es konnte weder ein CalDAV- noch ein CardDAV-Dienst gefunden werden.</string>
|
||||
<string name="login_no_service_info">Die Basis-URL scheint keine erreichbare CalDAV/CardDAV-URL zu sein und die Diensterkennung war nicht erfolgreich.</string>
|
||||
<string name="login_see_tested_services"><![CDATA[Bitte beachten Sie das Handbuch Ihres Dienstanbieters und <a href="%s">unsere Liste der getesteten Dienste</a> und deren Basis-URLs.]]></string>
|
||||
<string name="login_check_credentials">Bitte überprüfen Sie auch die Authentifizierung (normalerweise Benutzername und Passwort).</string>
|
||||
<string name="login_logs_available">Weitere technische Informationen sind in den Protokollen verfügbar.</string>
|
||||
<string name="login_view_logs">Protokoll anzeigen</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_sync">Synchronisierung</string>
|
||||
<string name="settings_sync_interval_contacts">Häufigkeit der Kontakte-Synchronisierung</string>
|
||||
<string name="settings_sync_summary_manually">Nur manuell</string>
|
||||
<string name="settings_sync_summary_periodically" tools:ignore="PluralsCandidate">Alle %d Minuten + sofort bei lokalen Änderungen</string>
|
||||
<string name="settings_sync_interval_calendars">Häufigkeit der Kalender-Synchronisierung</string>
|
||||
<string name="settings_sync_interval_tasks">Häufigkeit der Aufgaben-Synchronisierung</string>
|
||||
<string-array name="settings_sync_interval_names">
|
||||
<item>Nur manuell</item>
|
||||
<item>Alle 15 Minuten</item>
|
||||
<item>Alle 30 Minuten</item>
|
||||
<item>Jede Stunde</item>
|
||||
<item>Alle 2 Stunden</item>
|
||||
<item>Alle 4 Stunden</item>
|
||||
<item>Einmal am Tag</item>
|
||||
</string-array>
|
||||
<string name="settings_sync_wifi_only">Nur über WLAN synchronisieren</string>
|
||||
<string name="settings_sync_wifi_only_on">Synchronisierung nur bei aktiver WLAN-Verbindung</string>
|
||||
<string name="settings_sync_wifi_only_off">Verbindungstyp wird nicht beachtet</string>
|
||||
<string name="settings_sync_wifi_only_ssids">WLAN-SSID-Beschränkung</string>
|
||||
<string name="settings_sync_wifi_only_ssids_on">Synchronisierung nur über %s</string>
|
||||
<string name="settings_sync_wifi_only_ssids_off">Alle WLAN-Verbindungen werden verwendet</string>
|
||||
<string name="settings_sync_wifi_only_ssids_message">Erlaubte WLAN-Namen (SSIDs), mit Komma getrennt (leer lassen für alle)</string>
|
||||
<string name="settings_sync_wifi_only_ssids_permissions_required">WLAN-SSID-Einschränkung benötigt weitere Einstellungen</string>
|
||||
<string name="settings_sync_wifi_only_ssids_permissions_action">Verwalten</string>
|
||||
<string name="settings_ignore_vpns">VPN erfordert zugrundeliegendes Internet</string>
|
||||
<string name="settings_ignore_vpns_on">VPN ohne zugrundeliegende überprüfte Internetverbindung reicht für Synchronisierung nicht aus (empfohlen)</string>
|
||||
<string name="settings_ignore_vpns_off">VPN ohne zugrundeliegende überprüfte Internetverbindung reicht für Synchronisierung aus</string>
|
||||
<string name="settings_authentication">Anmeldeinformationen</string>
|
||||
<string name="settings_username">Benutzername</string>
|
||||
<string name="settings_password">Passwort oder App-Passwort</string>
|
||||
<string name="settings_app_password_hint"><![CDATA[Möglicherweise möchten Sie ein <a href="%1$s">App-Passwort</a> verwenden.]]></string>
|
||||
<string name="settings_new_password">Neues Passwort</string>
|
||||
<string name="settings_password_summary">Aktualisieren Sie Ihr Passwort gemäß den Server-Einstellungen.</string>
|
||||
<string name="settings_reauthorize_oauth">Erneut authentifizieren (OAuth)</string>
|
||||
<string name="settings_reauthorize_oauth_summary">Verwenden, wenn der Zugriff widerrufen wurde</string>
|
||||
<string name="settings_reauthorize_oauth_success">Authentifizierung erfolgreich</string>
|
||||
<string name="settings_certificate_alias">Client-Zertifikat</string>
|
||||
<string name="settings_certificate_alias_empty">Kein Zertifikat verfügbar oder ausgewählt</string>
|
||||
<string name="settings_certificate_install">Zertifikat installieren </string>
|
||||
<string name="settings_caldav">CalDAV</string>
|
||||
<string name="settings_sync_time_range_past">Abrufbeschränkung vergangener Termine</string>
|
||||
<string name="settings_sync_time_range_past_none">Alle Termine werden synchronisiert</string>
|
||||
<plurals name="settings_sync_time_range_past_days">
|
||||
<item quantity="one">Termine, die mehr als einen Tag in der Vergangenheit liegen, werden ignoriert</item>
|
||||
<item quantity="other">Termine, die mehr als %d Tage in der Vergangenheit liegen, werden ignoriert</item>
|
||||
</plurals>
|
||||
<string name="settings_sync_time_range_past_message">Termine, die mehr als diese Anzahl von Tagen in der Vergangenheit liegen, werden ignoriert (kann 0 sein). Feld leer lassen, um alle Termine zu synchronisieren.</string>
|
||||
<string name="settings_default_alarm">Standard-Erinnerung</string>
|
||||
<plurals name="settings_default_alarm_on">
|
||||
<item quantity="one">Standard-Erinnerung eine Minute vor dem Ereignis</item>
|
||||
<item quantity="other">Standard-Erinnerung %d Minuten vor dem Ereignis</item>
|
||||
</plurals>
|
||||
<string name="settings_default_alarm_off">Keine Standard-Erinnerungen</string>
|
||||
<string name="settings_default_alarm_message">Wenn Standard-Erinnerungen für Termine ohne Erinnerung erzeugt werden sollen: gewünschte Anzahl der Minuten vor dem Ereignis. Leer lassen, um Standard-Erinnerungen zu deaktivieren.</string>
|
||||
<string name="settings_manage_calendar_colors">Kalenderfarben verwalten</string>
|
||||
<string name="settings_manage_calendar_colors_on">Kalenderfarben werden bei jeder Synchronisierung neu gesetzt</string>
|
||||
<string name="settings_manage_calendar_colors_off">Kalenderfarben können von anderen Apps festgesetzt werden</string>
|
||||
<string name="settings_event_colors">Unterstützung für Terminfarben</string>
|
||||
<string name="settings_event_colors_on">Terminfarben werden synchronisiert</string>
|
||||
<string name="settings_event_colors_off">Terminfarben werden nicht synchronisiert</string>
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">Kontaktgruppen-Methode</string>
|
||||
<string-array name="settings_contact_group_method_entries">
|
||||
<item>Gruppen sind eigene vCards</item>
|
||||
<item>Gruppen sind Kategorien der Kontakte</item>
|
||||
</string-array>
|
||||
<!--CreateAddressBookScreen, CreateCalendarScreen-->
|
||||
<string name="create_addressbook">Adressbuch erstellen</string>
|
||||
<string name="create_addressbook_maybe_not_supported">Das Erstellen von Adressbüchern über CardDAV wird vom Server möglicherweise nicht unterstützt.</string>
|
||||
<string name="create_calendar">Kalender anlegen</string>
|
||||
<string name="create_calendar_time_zone_optional">Standard-Zeitzone (optional)</string>
|
||||
<string name="create_calendar_time_zone_none">—</string>
|
||||
<string name="create_calendar_type">Mögliche Kalendereinträge</string>
|
||||
<string name="create_calendar_type_vevent">Termine</string>
|
||||
<string name="create_calendar_type_vtodo">Aufgaben</string>
|
||||
<string name="create_calendar_type_vjournal">Notizen / Journal</string>
|
||||
<string name="create_calendar_maybe_not_supported">Das Erstellen von Kalendern über CardDAV wird vom Server möglicherweise nicht unterstützt.</string>
|
||||
<string name="create_collection_color">Farbe</string>
|
||||
<string name="create_collection_display_name">Titel</string>
|
||||
<string name="create_collection_home_set">Speicherort</string>
|
||||
<string name="create_collection_description_optional">Beschreibung (optional)</string>
|
||||
<string name="create_collection_create">Erstellen</string>
|
||||
<!--CollectionScreen-->
|
||||
<string name="collection_datatype_contacts">Kontakte</string>
|
||||
<string name="collection_datatype_events">Termine</string>
|
||||
<string name="collection_datatype_tasks">Aufgaben</string>
|
||||
<string name="collection_delete">Ordner löschen</string>
|
||||
<string name="collection_delete_warning">Dieser Ordner (%s) und alle enthaltenen Daten werden dauerhaft entfernt, sowohl lokal als auch auf dem Server.</string>
|
||||
<string name="collection_synchronization">Synchronisierung</string>
|
||||
<string name="collection_synchronization_on">Synchronisierung aktiviert</string>
|
||||
<string name="collection_synchronization_off">Synchronisierung deaktiviert</string>
|
||||
<string name="collection_read_only">Schreibgeschützt</string>
|
||||
<string name="collection_read_only_by_server">Schreibgeschützt (durch Server)</string>
|
||||
<string name="collection_read_only_by_setting">Schreibgeschützt (laut Richtlinie)</string>
|
||||
<string name="collection_read_only_forced">Schreibgeschützt (nur lokal)</string>
|
||||
<string name="collection_read_write">Lesen/Schreiben</string>
|
||||
<string name="collection_title">Titel</string>
|
||||
<string name="collection_description">Beschreibung</string>
|
||||
<string name="collection_owner">Besitzende Entität</string>
|
||||
<string name="collection_push_support">Push-Unterstützung</string>
|
||||
<string name="collection_push_web_push">Server bietet Push-Unterstützung</string>
|
||||
<string name="collection_push_subscribed_at">Um %1$s angemeldet, läuft ab %2$s</string>
|
||||
<string name="collection_last_sync">Letzte Synchronisierung (%s)</string>
|
||||
<string name="collection_url">Adresse (URL)</string>
|
||||
<!--debugging and DebugInfoActivity-->
|
||||
<string name="debug_info_title">Informationen zur Fehlersuche</string>
|
||||
<string name="debug_info_archive_caption">ZIP-Archiv</string>
|
||||
<string name="debug_info_archive_subtitle">Beinhaltet Debug-Info und Logs</string>
|
||||
<string name="debug_info_archive_text">Das Archiv teilen, um es zu einem Rechner zu übertragen, per Email zu verschicken oder an ein Support-Ticket anzuhängen.</string>
|
||||
<string name="debug_info_archive_share">Archiv teilen</string>
|
||||
<string name="debug_info_attached">Debug-Informationen sind dieser Nachricht beigelegt (benötigt Unterstützung für Anhänge in der empfangenden App).</string>
|
||||
<string name="debug_info_http_error">HTTP-Fehler</string>
|
||||
<string name="debug_info_server_error">Serverfehler</string>
|
||||
<string name="debug_info_webdav_error">WebDAV-Fehler</string>
|
||||
<string name="debug_info_io_error">E/A-Fehler</string>
|
||||
<string name="debug_info_http_403_description">Die Anfrage wurde vom Server abgelehnt.</string>
|
||||
<string name="debug_info_http_404_description">Die angeforderte Ressource existiert nicht (mehr).</string>
|
||||
<string name="debug_info_http_405_description">Der Server erlaubt die angeforderte Art der Operation nicht.</string>
|
||||
<string name="debug_info_http_5xx_description">Es trat ein serverseitiges Problem auf. Wenden Sie sich bitte an den Server-Support.</string>
|
||||
<string name="debug_info_unexpected_error">Es trat ein unerwarteter Fehler auf. Einzelheiten dazu finden Sie in der Debug-Info.</string>
|
||||
<string name="debug_info_view_details">Details anzeigen</string>
|
||||
<string name="debug_info_subtitle">Debug-Informationen wurden gesammelt</string>
|
||||
<string name="debug_info_involved_caption">Beteiligte Ressourcen</string>
|
||||
<string name="debug_info_involved_subtitle">Im Zusammenhang mit dem Problem</string>
|
||||
<string name="debug_info_involved_remote">Entfernte Ressource:</string>
|
||||
<string name="debug_info_involved_local">Lokale Ressource:</string>
|
||||
<string name="debug_info_logs_caption">Protokoll</string>
|
||||
<string name="debug_info_logs_subtitle">Ausführliches Protokoll verfügbar</string>
|
||||
<string name="debug_info_logs_view">Logs anzeigen</string>
|
||||
<string name="debug_info_copy_remote_url">URL kopieren</string>
|
||||
<string name="debug_info_view_local_resource">Ressource überprüfen</string>
|
||||
<string name="debug_info_privacy_warning_title">Datenschutzhinweis</string>
|
||||
<string name="debug_info_privacy_warning_description">Protokolle und Debug-Informationen können private Daten enthalten. Seien Sie sich dessen bewusst, wenn Sie diese öffentlich weitergeben.</string>
|
||||
<string name="debug_info_can_not_view_resource">Ressource kann nicht angezeigt werden</string>
|
||||
<!--ExceptionInfoFragment-->
|
||||
<string name="exception">Ein Fehler ist aufgetreten.</string>
|
||||
<string name="exception_httpexception">Ein HTTP-Fehler ist aufgetreten.</string>
|
||||
<string name="exception_ioexception">Ein E/A-Fehler ist aufgetreten.</string>
|
||||
<string name="exception_show_details">Details anzeigen</string>
|
||||
<!--WebDAV accounts-->
|
||||
<string name="webdav_mounts_title">WebDAV-Zugänge</string>
|
||||
<string name="webdav_mounts_quota_used_available">Speicher belegt: %1$s / verfügbar: %2$s</string>
|
||||
<string name="webdav_mounts_share_content">Inhalt teilen</string>
|
||||
<string name="webdav_mounts_unmount">Aushängen</string>
|
||||
<string name="webdav_add_mount_title">WebDAV-Zugang hinzufügen</string>
|
||||
<string name="webdav_mounts_empty">Greifen Sie mit einem WebDAV-Zugang direkt auf Ihre Cloud-Dateien zu!</string>
|
||||
<string name="webdav_add_mount_empty_more_info"><![CDATA[In der Anleitung erfahren Sie mehr darüber, <a href="%1$s">wie WebDAV-Zugänge funktionieren</a>.]]></string>
|
||||
<string name="webdav_add_mount_display_name">Anzeigename</string>
|
||||
<string name="webdav_add_mount_url">WebDAV-Adresse</string>
|
||||
<string name="webdav_add_mount_url_invalid">Ungültige Adresse</string>
|
||||
<string name="webdav_add_mount_mountpoint_displayname">Einhängepunkt und Anzeigename</string>
|
||||
<string name="webdav_add_mount_authentication">Anmeldeinformationen</string>
|
||||
<string name="webdav_add_mount_username">Anmeldename</string>
|
||||
<string name="webdav_add_mount_password">Passwort</string>
|
||||
<string name="webdav_add_mount_username_optional">Benutzername (optional)</string>
|
||||
<string name="webdav_add_mount_password_optional">Passwort (optional)</string>
|
||||
<string name="webdav_add_mount_add">Einhängen</string>
|
||||
<string name="webdav_add_mount_no_support">Kein WebDAV-Dienst unter dieser Adresse</string>
|
||||
<string name="webdav_remove_mount_title">Einhängepunkt entfernen</string>
|
||||
<string name="webdav_remove_mount_text">Verbindungsdetails werden verloren gehen, es werden aber keine Dateien gelöscht.</string>
|
||||
<string name="webdav_notification_access">WebDAV-Dateizugriff</string>
|
||||
<string name="webdav_notification_download">WebDAV-Download</string>
|
||||
<string name="webdav_notification_upload">WebDAV-Upload</string>
|
||||
<string name="webdav_provider_root_title">WebDAV-Zugang</string>
|
||||
<!--sync-->
|
||||
<string name="sync_error_permissions">DAVx⁵-Berechtigungen</string>
|
||||
<string name="sync_error_permissions_text">Zusätzliche Berechtigungen benötigt</string>
|
||||
<string name="sync_error_tasks_too_old">%s zu alt</string>
|
||||
<string name="sync_error_tasks_required_version">Benötigte Mindestversion: %1$s</string>
|
||||
<string name="sync_error_authentication_failed">Anmeldungsfehler (Login-Daten überprüfen)</string>
|
||||
<string name="sync_error_io">Netzwerk- oder E/A-Fehler – %s</string>
|
||||
<string name="sync_error_http_dav">HTTP-Serverfehler – %s</string>
|
||||
<string name="sync_error_local_storage">Lokaler Speicherfehler – %s</string>
|
||||
<string name="sync_error_retry_limit_reached">Weicher Fehler (maximale Anzahl an Wiederholungen erreicht)</string>
|
||||
<string name="sync_invalid_contact">Ungültigen Kontakt vom Server erhalten</string>
|
||||
<string name="sync_invalid_event">Ungültigen Termin vom Server erhalten</string>
|
||||
<string name="sync_invalid_task">Ungültige Aufgabe vom Server erhalten</string>
|
||||
<string name="sync_invalid_resources_ignoring">Eine/mehrere ungültige Ressourcen ignoriert</string>
|
||||
<string name="sync_notification_pending_push_title">Synchronisierung ausstehend</string>
|
||||
<string name="sync_notification_pending_push_message">Daten auf dem Server haben sich geändert</string>
|
||||
<!--widgets-->
|
||||
<string name="widget_sync_all">Alles synchronisieren</string>
|
||||
<string name="widget_sync_all_accounts">Alle Konten synchronisieren</string>
|
||||
<string name="widget_labeled_sync_label">Beschriftete Sync-Taste</string>
|
||||
<string name="widget_icon_sync_label">Sync-Taste-Symbol</string>
|
||||
<string name="widget_sync_description">Antippen, um die Synchronisierung manuell durchzuführen.</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="primaryColor">#7cb342</color>
|
||||
<color name="primaryLightColor">#aee571</color>
|
||||
<color name="primaryDarkColor">#4b830d</color>
|
||||
</resources>
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.push
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class DistributorPreferencesProvider @Inject constructor() : PushRegistrationManager.DistributorPreferences {
|
||||
// No special preferences for OSE flavor, select the first distributor available
|
||||
override val packageNames: List<String> = emptyList()
|
||||
}
|
||||
@@ -2,11 +2,13 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
|
||||
plugins {
|
||||
// These lines make sure that the plugins are applied in the same version to all subprojects.
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.android.library) apply false
|
||||
alias(libs.plugins.compose.compiler) apply false
|
||||
alias(libs.plugins.hilt) apply false
|
||||
alias(libs.plugins.ksp) apply false
|
||||
|
||||
alias(libs.plugins.mikepenz.aboutLibraries.android) apply false
|
||||
}
|
||||
0
app/.gitignore → core/.gitignore
vendored
0
app/.gitignore → core/.gitignore
vendored
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.compose.compiler)
|
||||
alias(libs.plugins.hilt)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
@@ -16,20 +16,12 @@ 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"
|
||||
|
||||
// include these rules in the app that uses the core library
|
||||
consumerProguardFile("core-proguard-rules.pro")
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -53,37 +45,9 @@ 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 = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
|
||||
|
||||
isShrinkResources = true
|
||||
|
||||
signingConfig = signingConfigs.findByName("bitfire")
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +55,6 @@ 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
|
||||
@@ -102,6 +62,12 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("androidTest") {
|
||||
assets.srcDir("$projectDir/schemas")
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
testOptions {
|
||||
managedDevices {
|
||||
@@ -130,7 +96,7 @@ aboutLibraries {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// core
|
||||
// Kotlin / Android
|
||||
implementation(libs.kotlin.stdlib)
|
||||
implementation(libs.kotlinx.coroutines)
|
||||
coreLibraryDesugaring(libs.android.desugaring)
|
||||
@@ -167,7 +133,7 @@ dependencies {
|
||||
|
||||
// Glance Widgets
|
||||
implementation(libs.androidx.glance.base)
|
||||
implementation(libs.androidx.glance.material)
|
||||
implementation(libs.androidx.glance.material3)
|
||||
|
||||
// Jetpack Room
|
||||
implementation(libs.androidx.room.runtime)
|
||||
@@ -1,13 +1,4 @@
|
||||
|
||||
# R8 usage for DAVx⁵:
|
||||
# shrinking yes (only in release builds)
|
||||
# optimization yes (on by R8 defaults)
|
||||
# full-mode no (see gradle.properties)
|
||||
# obfuscation no (open-source)
|
||||
|
||||
-dontobfuscate
|
||||
-printusage build/reports/r8-usage.txt
|
||||
|
||||
# keep rules
|
||||
-keep class at.bitfire.** { *; } # all DAVx5 code is required
|
||||
-keep class org.xmlpull.** { *; }
|
||||
@@ -10,7 +10,6 @@ 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
|
||||
@@ -29,7 +28,7 @@ class HiltTestRunner : AndroidJUnitRunner() {
|
||||
val rootLogger = Logger.getLogger("")
|
||||
rootLogger.level = Level.ALL
|
||||
rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
|
||||
rootLogger.addHandler(LogcatHandler(BuildConfig.APPLICATION_ID))
|
||||
rootLogger.addHandler(LogcatHandler(javaClass.name))
|
||||
|
||||
// MockK requirements
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
|
||||
@@ -28,11 +28,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
|
||||
""".trimIndent()
|
||||
db.execSQL(
|
||||
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
|
||||
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
)
|
||||
db.execSQL(
|
||||
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone)
|
||||
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone)
|
||||
)
|
||||
}
|
||||
) { db ->
|
||||
@@ -47,11 +47,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
|
||||
prepare = { db ->
|
||||
db.execSQL(
|
||||
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
|
||||
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
)
|
||||
db.execSQL(
|
||||
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content")
|
||||
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content")
|
||||
)
|
||||
}
|
||||
) { db ->
|
||||
@@ -66,11 +66,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
|
||||
prepare = { db ->
|
||||
db.execSQL(
|
||||
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
|
||||
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
|
||||
)
|
||||
db.execSQL(
|
||||
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false)
|
||||
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false)
|
||||
)
|
||||
}
|
||||
) { db ->
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.cert4android.CustomCertManager
|
||||
import at.bitfire.cert4android.CustomCertStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import java.util.Optional
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class Cert4AndroidModule {
|
||||
|
||||
@Provides
|
||||
fun customCertManager(): Optional<CustomCertManager> = Optional.empty()
|
||||
|
||||
@Provides
|
||||
fun customHostnameVerifier(): Optional<CustomCertManager.HostnameVerifier> = Optional.empty()
|
||||
|
||||
@Provides
|
||||
fun customCertStore(): Optional<CustomCertStore> = Optional.empty()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.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
|
||||
|
||||
}
|
||||
@@ -5,6 +5,10 @@
|
||||
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
|
||||
@@ -4,14 +4,12 @@
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.davdroid.push.DistributorPreferencesProvider
|
||||
import at.bitfire.davdroid.push.PushRegistrationManager
|
||||
import at.bitfire.davdroid.ui.AccountsDrawerHandler
|
||||
import at.bitfire.davdroid.ui.OseAccountsDrawerHandler
|
||||
import at.bitfire.davdroid.ui.about.AboutActivity
|
||||
import at.bitfire.davdroid.ui.about.OpenSourceLicenseInfoProvider
|
||||
import at.bitfire.davdroid.ui.about.FakeAppLicenseInfoProvider
|
||||
import at.bitfire.davdroid.ui.intro.FakeIntroPageFactory
|
||||
import at.bitfire.davdroid.ui.intro.IntroPageFactory
|
||||
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory
|
||||
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
|
||||
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
|
||||
import dagger.Binds
|
||||
@@ -37,7 +35,7 @@ interface OseModules {
|
||||
@InstallIn(ViewModelComponent::class)
|
||||
interface ForViewModels {
|
||||
@Binds
|
||||
fun appLicenseInfoProvider(impl: OpenSourceLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
|
||||
fun appLicenseInfoProvider(impl: FakeAppLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
|
||||
|
||||
@Binds
|
||||
fun loginTypesProvider(impl: StandardLoginTypesProvider): LoginTypesProvider
|
||||
@@ -47,10 +45,7 @@ interface OseModules {
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface Global {
|
||||
@Binds
|
||||
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory
|
||||
|
||||
@Binds
|
||||
fun pushDistributorPreferences(impl: DistributorPreferencesProvider): PushRegistrationManager.DistributorPreferences
|
||||
fun introPageFactory(impl: FakeIntroPageFactory): IntroPageFactory
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,20 +5,20 @@
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.davdroid.startup.StartupPlugin
|
||||
import at.bitfire.davdroid.startup.TasksAppWatcher
|
||||
import dagger.Module
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.hilt.testing.TestInstallIn
|
||||
import dagger.multibindings.Multibinds
|
||||
|
||||
// remove TasksAppWatcherModule from Android tests
|
||||
@Module
|
||||
@TestInstallIn(
|
||||
components = [SingletonComponent::class],
|
||||
replaces = [TasksAppWatcher.TasksAppWatcherModule::class]
|
||||
replaces = [StartupPluginsModule::class]
|
||||
)
|
||||
abstract class TestTasksAppWatcherModule {
|
||||
// provides empty set of plugins
|
||||
abstract class TestStartupPluginsModule {
|
||||
|
||||
// provides empty set of startup plugins so that nothing interferes with tests
|
||||
@Multibinds
|
||||
abstract fun empty(): Set<StartupPlugin>
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user