mirror of
https://github.com/bitfireAT/davx5-ose.git
synced 2026-02-05 20:51:21 -05:00
Compare commits
5 Commits
v4.5.9-ose
...
split-core
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38bad81c55 | ||
|
|
31a7ad0939 | ||
|
|
5e84648fb4 | ||
|
|
490abcb88a | ||
|
|
cca12e79d8 |
@@ -26,9 +26,6 @@ android {
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -51,7 +48,7 @@ android {
|
||||
}
|
||||
|
||||
// Java namespace for our classes (not to be confused with Android package ID)
|
||||
namespace = "at.bitfire.davdroid"
|
||||
namespace = "com.davx5.ose"
|
||||
|
||||
flavorDimensions += "distribution"
|
||||
productFlavors {
|
||||
@@ -130,7 +127,10 @@ aboutLibraries {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// core
|
||||
// app core
|
||||
implementation(project(":core"))
|
||||
|
||||
// Kotlin / Android
|
||||
implementation(libs.kotlin.stdlib)
|
||||
implementation(libs.kotlinx.coroutines)
|
||||
coreLibraryDesugaring(libs.android.desugaring)
|
||||
@@ -167,7 +167,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)
|
||||
|
||||
@@ -4,350 +4,15 @@
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="internalOnly">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="internalOnly">
|
||||
|
||||
<!-- normal permissions -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.READ_SYNC_STATS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
|
||||
<!-- other permissions -->
|
||||
<!-- android.permission-group.CONTACTS -->
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
||||
<!-- android.permission-group.CALENDAR -->
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR"/>
|
||||
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
|
||||
|
||||
<!-- android.permission-group.LOCATION -->
|
||||
<!-- getting the WiFi name (for "sync in Wifi only") requires
|
||||
- coarse location (Android 8.1)
|
||||
- fine location (Android 10) -->
|
||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<!-- required since Android 10 to get the WiFi name while in background (= while syncing) -->
|
||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
|
||||
|
||||
<!-- ical4android declares task access permissions -->
|
||||
|
||||
<!-- Disable GPS capability requirement, which is implicitly derived from ACCESS_FINE_LOCATION
|
||||
permission and makes app unusable on some devices without GPS. We need location permissions only
|
||||
to get the current WiFi SSID, and we don't need GPS for that. -->
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
|
||||
android:resizeableActivity="true"
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:supportsRtl="true">
|
||||
|
||||
<!-- 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 android:name=".App">
|
||||
|
||||
<!-- Remove the node added by AppAuth (remove only from net.openid.appauth library, not from our flavor manifest files) -->
|
||||
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
|
||||
tools:node="remove" tools:selector="net.openid.appauth"/>
|
||||
|
||||
<activity android:name=".ui.intro.IntroActivity" />
|
||||
<activity
|
||||
android:name=".ui.AccountsActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.about.AboutActivity"
|
||||
android:label="@string/navigation_drawer_about"
|
||||
android:parentActivityName=".ui.AccountsActivity"/>
|
||||
|
||||
<activity
|
||||
android:name=".ui.AppSettingsActivity"
|
||||
android:label="@string/app_settings"
|
||||
android:parentActivityName=".ui.AccountsActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.DebugInfoActivity"
|
||||
android:parentActivityName=".ui.AppSettingsActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/debug_info_title">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BUG_REPORT"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.PermissionsActivity"
|
||||
android:label="@string/app_settings_security_app_permissions"
|
||||
android:parentActivityName=".ui.AppSettingsActivity" />
|
||||
<activity
|
||||
android:name=".ui.TasksActivity"
|
||||
android:label="@string/intro_tasks_title"
|
||||
android:parentActivityName=".ui.AppSettingsActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.setup.LoginActivity"
|
||||
android:parentActivityName=".ui.AccountsActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:scheme="caldav"/>
|
||||
<data android:scheme="caldavs"/>
|
||||
<data android:scheme="carddav"/>
|
||||
<data android:scheme="carddavs"/>
|
||||
<data android:scheme="davx5"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="loginFlow" /> <!-- Ensures this filter matches, even if the sending app is not defining an action -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data
|
||||
tools:ignore="AppLinkUrlError"
|
||||
android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.account.AccountActivity"
|
||||
android:parentActivityName=".ui.AccountsActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.account.CollectionActivity"
|
||||
android:parentActivityName=".ui.account.AccountActivity" />
|
||||
<activity
|
||||
android:name=".ui.account.CreateAddressBookActivity"
|
||||
android:parentActivityName=".ui.account.AccountActivity" />
|
||||
<activity
|
||||
android:name=".ui.account.CreateCalendarActivity"
|
||||
android:parentActivityName=".ui.account.AccountActivity" />
|
||||
<activity
|
||||
android:name=".ui.account.AccountSettingsActivity"
|
||||
android:parentActivityName=".ui.account.AccountActivity" />
|
||||
<activity
|
||||
android:name=".ui.account.WifiPermissionsActivity"
|
||||
android:parentActivityName=".ui.account.AccountSettingsActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.webdav.WebdavMountsActivity"
|
||||
android:exported="true"
|
||||
android:parentActivityName=".ui.AccountsActivity" />
|
||||
<activity
|
||||
android:name=".ui.webdav.AddWebdavMountActivity"
|
||||
android:parentActivityName=".ui.webdav.WebdavMountsActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<!-- account type "DAVx⁵" -->
|
||||
<service
|
||||
android:name=".sync.account.AccountAuthenticatorService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator"/>
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/account_authenticator"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".sync.adapter.CalendarsSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_calendars"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".sync.adapter.JtxSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_notes"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".sync.adapter.OpenTasksSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_opentasks"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".sync.adapter.TasksOrgSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_tasks_org"/>
|
||||
</service>
|
||||
<provider
|
||||
android:authorities="@string/webdav_authority"
|
||||
android:name=".webdav.DavDocumentsProvider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
|
||||
<!-- account type "DAVx⁵ Address book" -->
|
||||
<service
|
||||
android:name=".sync.account.AddressBookAuthenticatorService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService"> <!-- Since Android 11, this must be true so that Google Contacts shows the address book accounts -->
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/account_authenticator_address_book"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".sync.adapter.ContactsSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_contacts"/>
|
||||
<meta-data
|
||||
android:name="android.provider.CONTACTS_STRUCTURE"
|
||||
android:resource="@xml/contacts"/>
|
||||
</service>
|
||||
|
||||
<!-- provider to share debug info/logs -->
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="@string/authority_debug_provider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/debug_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- UnifiedPush -->
|
||||
<service android:exported="false" android:name=".push.UnifiedPushService">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.connector.PUSH_EVENT"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<!-- Widgets -->
|
||||
<receiver android:name=".ui.widget.LabeledSyncButtonWidgetReceiver"
|
||||
android:label="@string/widget_labeled_sync_label"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_info_labeled_sync_button" />
|
||||
</receiver>
|
||||
<receiver android:name=".ui.widget.IconSyncButtonWidgetReceiver"
|
||||
android:label="@string/widget_icon_sync_label"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_info_icon_sync_button" />
|
||||
</receiver>
|
||||
tools:node="remove" tools:selector="net.openid.appauth"/>
|
||||
|
||||
</application>
|
||||
|
||||
<!-- package visiblity – which apps do we need to see? -->
|
||||
<queries>
|
||||
<!-- system providers (listing them is technically not required, but some apps like the
|
||||
Huawei calendar take this as indication of whether these providers are accessed) -->
|
||||
<provider android:authorities="com.android.calendar"/>
|
||||
<provider android:authorities="com.android.contacts"/>
|
||||
|
||||
<!-- task providers -->
|
||||
<package android:name="at.techbee.jtx" />
|
||||
<package android:name="org.dmfs.tasks" />
|
||||
<package android:name="org.tasks" />
|
||||
|
||||
<!-- ICSx5 for Webcal feeds -->
|
||||
<package android:name="at.bitfire.icsdroid"/>
|
||||
|
||||
<!-- apps that interact with contact, calendar, task data (for debug info) -->
|
||||
<intent>
|
||||
<action android:name="*" />
|
||||
<data android:scheme="content" android:host="com.android.contacts" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="*" />
|
||||
<data android:scheme="content" android:host="com.android.calendar" />
|
||||
</intent>
|
||||
|
||||
<!-- Open URLs in a browser or other app [https://developer.android.com/training/package-visibility/use-cases#open-urls-browser-or-other-app] -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
|
||||
<!-- Custom Tabs support (e.g. Nextcloud Login Flow) -->
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
</manifest>
|
||||
@@ -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,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()
|
||||
}
|
||||
@@ -2,12 +2,12 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid
|
||||
package com.davx5.ose
|
||||
|
||||
import android.app.Application
|
||||
import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
import at.bitfire.davdroid.di.DefaultDispatcher
|
||||
import at.bitfire.davdroid.di.scope.DefaultDispatcher
|
||||
import at.bitfire.davdroid.log.LogManager
|
||||
import at.bitfire.davdroid.startup.StartupPlugin
|
||||
import at.bitfire.davdroid.sync.account.AccountsCleanupWorker
|
||||
@@ -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
|
||||
@@ -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
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class CustomCertManagerModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun customCertManager(
|
||||
@ApplicationContext context: Context,
|
||||
settings: SettingsManager
|
||||
): Optional<CustomCertManager> =
|
||||
if (BuildConfig.allowCustomCerts)
|
||||
Optional.of(CustomCertManager(
|
||||
certStore = CustomCertStore.getInstance(context),
|
||||
settings = object : SettingsProvider {
|
||||
|
||||
override val appInForeground: Boolean
|
||||
get() = ForegroundTracker.inForeground.value
|
||||
|
||||
override val trustSystemCerts: Boolean
|
||||
get() = !settings.getBoolean(Settings.DISTRUST_SYSTEM_CERTIFICATES)
|
||||
|
||||
}
|
||||
))
|
||||
else
|
||||
Optional.empty()
|
||||
fun customCertStore(@ApplicationContext context: Context): Optional<CustomCertStore> =
|
||||
Optional.of(CustomCertStore.getInstance(context))
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Reusable
|
||||
fun customCertManager(
|
||||
customCertStore: Optional<CustomCertStore>,
|
||||
settings: SettingsManager
|
||||
): Optional<CustomCertManager> =
|
||||
Optional.of(
|
||||
CustomCertManager(
|
||||
certStore = customCertStore.get(),
|
||||
settings = object : SettingsProvider {
|
||||
|
||||
override val appInForeground: Boolean
|
||||
get() = ForegroundTracker.inForeground.value
|
||||
|
||||
override val trustSystemCerts: Boolean
|
||||
get() = !settings.getBoolean(Settings.DISTRUST_SYSTEM_CERTIFICATES)
|
||||
|
||||
}
|
||||
))
|
||||
|
||||
@Provides
|
||||
@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))
|
||||
|
||||
}
|
||||
28
app/src/ose/kotlin/com/davx5/ose/di/OseColorSchemesModule.kt
Normal file
28
app/src/ose/kotlin/com/davx5/ose/di/OseColorSchemesModule.kt
Normal file
@@ -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.scope.DarkColorScheme
|
||||
import at.bitfire.davdroid.di.scope.LightColorScheme
|
||||
import com.davx5.ose.ui.OseTheme
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class OseColorSchemesModule {
|
||||
|
||||
@Provides
|
||||
@LightColorScheme
|
||||
fun lightColorScheme(): ColorScheme = OseTheme.lightScheme
|
||||
|
||||
@Provides
|
||||
@DarkColorScheme
|
||||
fun darkColorScheme(): ColorScheme = OseTheme.darkScheme
|
||||
|
||||
}
|
||||
@@ -2,16 +2,16 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
package com.davx5.ose.di
|
||||
|
||||
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.intro.IntroPageFactory
|
||||
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory
|
||||
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
|
||||
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
|
||||
import com.davx5.ose.ui.about.OpenSourceLicenseInfoProvider
|
||||
import com.davx5.ose.ui.intro.OseIntroPageFactory
|
||||
import com.davx5.ose.ui.setup.StandardLoginTypesProvider
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -2,14 +2,13 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui
|
||||
package com.davx5.ose.ui
|
||||
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
object M3ColorScheme {
|
||||
object OseTheme {
|
||||
|
||||
// All colors hand-crafted because Material Theme Builder generates unbelievably ugly colors
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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.text.Spanned
|
||||
@@ -18,6 +18,7 @@ import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
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
|
||||
@@ -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(
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.setup
|
||||
package com.davx5.ose.ui.setup
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -24,6 +25,8 @@ import at.bitfire.davdroid.ui.ExternalUris
|
||||
import at.bitfire.davdroid.ui.ExternalUris.withStatParams
|
||||
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
|
||||
import at.bitfire.davdroid.ui.composable.Assistant
|
||||
import at.bitfire.davdroid.ui.setup.LoginInfo
|
||||
import at.bitfire.davdroid.ui.setup.LoginType
|
||||
|
||||
@Composable
|
||||
fun StandardLoginTypePage(
|
||||
@@ -67,9 +70,10 @@ fun StandardLoginTypePage(
|
||||
|
||||
HorizontalDivider(Modifier.padding(vertical = 12.dp))
|
||||
|
||||
val context = LocalContext.current
|
||||
val privacyPolicy = ExternalUris.Homepage.baseUrl.buildUpon()
|
||||
.appendPath(ExternalUris.Homepage.PATH_PRIVACY)
|
||||
.withStatParams("StandardLoginTypePage")
|
||||
.withStatParams(context, "StandardLoginTypePage")
|
||||
.build().toString()
|
||||
val privacy = HtmlCompat.fromHtml(
|
||||
stringResource(R.string.login_privacy_hint, stringResource(R.string.app_name), privacyPolicy),
|
||||
@@ -2,12 +2,22 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.ui.setup
|
||||
package com.davx5.ose.ui.setup
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import at.bitfire.davdroid.ui.setup.AdvancedLogin
|
||||
import at.bitfire.davdroid.ui.setup.EmailLogin
|
||||
import at.bitfire.davdroid.ui.setup.FastmailLogin
|
||||
import at.bitfire.davdroid.ui.setup.GoogleLogin
|
||||
import at.bitfire.davdroid.ui.setup.LoginActivity
|
||||
import at.bitfire.davdroid.ui.setup.LoginInfo
|
||||
import at.bitfire.davdroid.ui.setup.LoginType
|
||||
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
|
||||
import at.bitfire.davdroid.ui.setup.LoginTypesProvider.LoginAction
|
||||
import at.bitfire.davdroid.ui.setup.NextcloudLogin
|
||||
import at.bitfire.davdroid.ui.setup.UrlLogin
|
||||
import java.util.logging.Logger
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
plugins {
|
||||
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
|
||||
|
||||
0
app/.gitignore → core/.gitignore
vendored
0
app/.gitignore → core/.gitignore
vendored
196
core/build.gradle.kts
Normal file
196
core/build.gradle.kts
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.compose.compiler)
|
||||
alias(libs.plugins.hilt)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.mikepenz.aboutLibraries.android)
|
||||
}
|
||||
|
||||
// Android configuration
|
||||
android {
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24 // Android 7.0
|
||||
|
||||
testInstrumentationRunner = "at.bitfire.davdroid.HiltTestRunner"
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
// required for
|
||||
// - dnsjava 3.x: java.nio.file.Path
|
||||
// - ical4android: time API
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
compose = true
|
||||
}
|
||||
|
||||
// Java namespace for our classes (not to be confused with Android package ID)
|
||||
namespace = "at.bitfire.davdroid"
|
||||
|
||||
sourceSets {
|
||||
getByName("androidTest") {
|
||||
assets.srcDir("$projectDir/schemas")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
disable += arrayOf("GoogleAppIndexingWarning", "ImpliedQuantity", "MissingQuantity", "MissingTranslation", "ExtraTranslation", "RtlEnabled", "RtlHardcoded", "Typos")
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
// multiple (test) dependencies have LICENSE files at same location
|
||||
merges += arrayOf("META-INF/LICENSE*")
|
||||
}
|
||||
}
|
||||
|
||||
@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksp {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
|
||||
aboutLibraries {
|
||||
export {
|
||||
// exclude timestamps for reproducible builds [https://github.com/bitfireAT/davx5-ose/issues/994]
|
||||
excludeFields.add("generated")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// 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.activityCompose)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.browser)
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.androidx.hilt.navigation.compose)
|
||||
implementation(libs.androidx.hilt.work)
|
||||
implementation(libs.androidx.lifecycle.runtime.compose)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.base)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||
implementation(libs.androidx.paging)
|
||||
implementation(libs.androidx.paging.compose)
|
||||
implementation(libs.androidx.preference)
|
||||
implementation(libs.androidx.security)
|
||||
implementation(libs.androidx.work.base)
|
||||
|
||||
// Jetpack Compose
|
||||
implementation(libs.compose.accompanist.permissions)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.compose.material3.adaptive)
|
||||
implementation(libs.androidx.compose.materialIconsExtended)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
implementation(libs.androidx.compose.ui.toolingPreview)
|
||||
|
||||
// Glance Widgets
|
||||
implementation(libs.androidx.glance.base)
|
||||
implementation(libs.androidx.glance.material3)
|
||||
|
||||
// Jetpack Room
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.androidx.room.base)
|
||||
implementation(libs.androidx.room.paging)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
|
||||
// own libraries
|
||||
implementation(libs.bitfire.cert4android)
|
||||
implementation(libs.bitfire.dav4jvm) {
|
||||
exclude(group="junit")
|
||||
exclude(group="org.ogce", module="xpp3") // Android has its own XmlPullParser implementation
|
||||
}
|
||||
implementation(libs.bitfire.synctools) {
|
||||
exclude(group="androidx.test") // synctools declares test rules, but we don't want them in non-test code
|
||||
exclude(group = "junit")
|
||||
}
|
||||
|
||||
// third-party libs
|
||||
implementation(libs.conscrypt)
|
||||
implementation(libs.dnsjava)
|
||||
implementation(libs.guava)
|
||||
implementation(libs.ktor.client.content.negotiation)
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.okhttp)
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(libs.mikepenz.aboutLibraries.m3)
|
||||
implementation(libs.okhttp.base)
|
||||
implementation(libs.okhttp.brotli)
|
||||
implementation(libs.okhttp.logging)
|
||||
implementation(libs.openid.appauth)
|
||||
implementation(libs.unifiedpush) {
|
||||
// UnifiedPush connector seems to be using a workaround by importing this library.
|
||||
// Will be removed after https://github.com/tink-crypto/tink-java-apps/pull/5 is merged.
|
||||
// See: https://codeberg.org/UnifiedPush/android-connector/src/commit/28cb0d622ed0a972996041ab9cc85b701abc48c6/connector/build.gradle#L56-L59
|
||||
exclude(group = "com.google.crypto.tink", module = "tink")
|
||||
}
|
||||
implementation(libs.unifiedpush.fcm)
|
||||
|
||||
// force some versions for compatibility with our minSdk level (see version catalog for details)
|
||||
implementation(libs.commons.codec)
|
||||
implementation(libs.commons.lang)
|
||||
|
||||
// for tests
|
||||
androidTestImplementation(libs.androidx.arch.core.testing)
|
||||
androidTestImplementation(libs.androidx.room.testing)
|
||||
androidTestImplementation(libs.androidx.test.core)
|
||||
androidTestImplementation(libs.androidx.test.junit)
|
||||
androidTestImplementation(libs.androidx.test.rules)
|
||||
androidTestImplementation(libs.androidx.test.runner)
|
||||
androidTestImplementation(libs.androidx.work.testing)
|
||||
androidTestImplementation(libs.hilt.android.testing)
|
||||
androidTestImplementation(libs.junit)
|
||||
androidTestImplementation(libs.kotlinx.coroutines.test)
|
||||
androidTestImplementation(libs.mockk.android)
|
||||
androidTestImplementation(libs.okhttp.mockwebserver)
|
||||
|
||||
testImplementation(libs.bitfire.dav4jvm)
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.mockk)
|
||||
testImplementation(libs.okhttp.mockwebserver)
|
||||
testImplementation(libs.robolectric)
|
||||
}
|
||||
@@ -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)
|
||||
@@ -5,6 +5,10 @@
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule.standardTestDispatcher
|
||||
import at.bitfire.davdroid.di.scope.DefaultDispatcher
|
||||
import at.bitfire.davdroid.di.scope.IoDispatcher
|
||||
import at.bitfire.davdroid.di.scope.MainDispatcher
|
||||
import at.bitfire.davdroid.di.scope.SyncDispatcher
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
@@ -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.SyncDispatcher
|
||||
import at.bitfire.davdroid.di.scope.SyncDispatcher
|
||||
import at.bitfire.davdroid.resource.LocalResource
|
||||
import at.bitfire.davdroid.resource.SyncState
|
||||
import at.bitfire.davdroid.util.DavUtils.lastSegment
|
||||
@@ -5,7 +5,7 @@
|
||||
package at.bitfire.davdroid.ui
|
||||
|
||||
import android.content.Context
|
||||
import at.bitfire.davdroid.di.IoDispatcher
|
||||
import at.bitfire.davdroid.di.scope.IoDispatcher
|
||||
import at.bitfire.davdroid.ui.about.AboutModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user