diff --git a/Android.bp b/Android.bp index 46529b7a2..d91128085 100644 --- a/Android.bp +++ b/Android.bp @@ -26,7 +26,8 @@ android_app { "com.google.android.material_material", "kotlinx-coroutines-android", "kotlinx-coroutines-core", - // storage backup lib + // our own gradle module libs + "seedvault-lib-core", "seedvault-lib-storage", // koin "seedvault-lib-koin-core-jvm", // did not manage to add this as transitive dependency @@ -36,7 +37,6 @@ android_app { // WebDAV "seedvault-lib-dav4jvm", "seedvault-lib-okhttp", - "seedvault-lib-okio", ], manifest: "app/src/main/AndroidManifest.xml", diff --git a/app/src/main/java/com/stevesoltys/seedvault/App.kt b/app/src/main/java/com/stevesoltys/seedvault/App.kt index a62710ecc..afc5bc74e 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/App.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/App.kt @@ -20,13 +20,13 @@ import android.os.UserManager import androidx.work.ExistingPeriodicWorkPolicy.UPDATE import androidx.work.WorkManager import com.google.android.material.color.DynamicColors +import com.stevesoltys.seedvault.backend.BackendManager +import com.stevesoltys.seedvault.backend.saf.storagePluginModuleSaf +import com.stevesoltys.seedvault.backend.webdav.storagePluginModuleWebDav import com.stevesoltys.seedvault.crypto.cryptoModule import com.stevesoltys.seedvault.header.headerModule import com.stevesoltys.seedvault.metadata.MetadataManager import com.stevesoltys.seedvault.metadata.metadataModule -import com.stevesoltys.seedvault.backend.BackendManager -import com.stevesoltys.seedvault.backend.saf.storagePluginModuleSaf -import com.stevesoltys.seedvault.backend.webdav.storagePluginModuleWebDav import com.stevesoltys.seedvault.restore.install.installModule import com.stevesoltys.seedvault.restore.restoreUiModule import com.stevesoltys.seedvault.settings.AppListRetriever @@ -63,7 +63,14 @@ open class App : Application() { single { SettingsManager(this@App) } single { BackupNotificationManager(this@App) } single { BackendManager(this@App, get(), get()) } - single { BackendFactory(this@App) } + single { + BackendFactory { + // uses context of the device's main user to be able to access USB storage + this@App.applicationContext.getStorageContext { + get().getSafProperties()?.isUsb == true + } + } + } single { BackupStateManager(this@App) } single { Clock() } factory { IBackupManager.Stub.asInterface(getService(BACKUP_SERVICE)) } @@ -215,6 +222,10 @@ fun permitDiskReads(func: () -> T): T { } } +/** + * Hack to allow other profiles access to USB backend. + * @return the context of the device's main user, so use with great care! + */ @Suppress("MissingPermission") fun Context.getStorageContext(isUsbStorage: () -> Boolean): Context { if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED && isUsbStorage()) { diff --git a/core/Android.bp b/core/Android.bp new file mode 100644 index 000000000..6922e7f55 --- /dev/null +++ b/core/Android.bp @@ -0,0 +1,35 @@ +// +// SPDX-FileCopyrightText: 2021 The Calyx Institute +// SPDX-License-Identifier: Apache-2.0 +// + +android_library { + name: "seedvault-lib-core", + sdk_version: "current", + srcs: [ + "src/main/java/**/*.kt", + "src/main/java/**/*.java", + ], + exclude_srcs: [ + "src/main/java/org/calyxos/seedvault/core/backends/BackendTest.kt", + ], + static_libs: [ + "androidx.core_core-ktx", + "androidx.documentfile_documentfile", + "kotlinx-coroutines-android", + "kotlinx-coroutines-core", + "seedvault-lib-kotlin-logging-jvm", + "seedvault-lib-slf4j-api", + // WebDAV + "seedvault-lib-dav4jvm", + "seedvault-lib-okhttp", + "okio-lib", + ], + manifest: "src/main/AndroidManifest.xml", + optimize: { + enabled: false, + }, + kotlincflags: [ + "-opt-in=kotlin.RequiresOptIn", + ], +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 201768ab0..daed7a8f4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -36,17 +36,17 @@ android { dependencies { val aospLibs: FileTree by rootProject.extra compileOnly(aospLibs) - compileOnly("org.ogce:xpp3:1.1.6") compileOnly(kotlin("test")) implementation(libs.bundles.kotlin) implementation(libs.bundles.coroutines) implementation(libs.androidx.documentfile) implementation(libs.androidx.core.ktx) - // implementation(fileTree("${rootProject.rootDir}/libs/dav4jvm").include("okio-jvm-3.7.0.jar")) implementation(fileTree("${rootProject.rootDir}/libs/dav4jvm").include("*.jar")) - implementation("io.github.oshai:kotlin-logging-jvm:6.0.3") - implementation("org.slf4j:slf4j-simple:2.0.3") + implementation(libs.squareup.okio) + implementation(libs.kotlin.logging) + implementation(libs.slf4j.api) testImplementation(kotlin("test")) testImplementation("org.ogce:xpp3:1.1.6") + testImplementation("org.slf4j:slf4j-simple:2.0.3") } diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 6c244e77d..6099552b2 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -2,7 +2,8 @@ SPDX-FileCopyrightText: 2021 The Calyx Institute SPDX-License-Identifier: Apache-2.0 --> - + diff --git a/core/src/main/java/org/calyxos/seedvault/core/Utils.kt b/core/src/main/java/org/calyxos/seedvault/core/Utils.kt deleted file mode 100644 index 28982dfa6..000000000 --- a/core/src/main/java/org/calyxos/seedvault/core/Utils.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 The Calyx Institute - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.calyxos.seedvault.core - -import android.Manifest.permission.INTERACT_ACROSS_USERS_FULL -import android.content.Context -import android.content.pm.PackageManager.PERMISSION_GRANTED -import android.os.UserManager - -/** - * Hack to allow other profiles access to USB backend. - * @return the context of the device's main user, so use with great care! - */ -@Suppress("MissingPermission") -public fun Context.getBackendContext(isUsbStorage: () -> Boolean): Context { - if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED && isUsbStorage()) { - UserManager.get(this).getProfileParent(user) - ?.let { parent -> return createContextAsUser(parent, 0) } - } - return this -} diff --git a/core/src/main/java/org/calyxos/seedvault/core/backends/BackendFactory.kt b/core/src/main/java/org/calyxos/seedvault/core/backends/BackendFactory.kt index 953e0c56c..f05bcb549 100644 --- a/core/src/main/java/org/calyxos/seedvault/core/backends/BackendFactory.kt +++ b/core/src/main/java/org/calyxos/seedvault/core/backends/BackendFactory.kt @@ -12,8 +12,10 @@ import org.calyxos.seedvault.core.backends.webdav.WebDavBackend import org.calyxos.seedvault.core.backends.webdav.WebDavConfig public class BackendFactory( - private val context: Context, + private val contextGetter: () -> Context, ) { - public fun createSafBackend(config: SafProperties): Backend = SafBackend(context, config) + public fun createSafBackend(config: SafProperties): Backend = + SafBackend(contextGetter(), config) + public fun createWebDavBackend(config: WebDavConfig): Backend = WebDavBackend(config) } diff --git a/core/src/main/java/org/calyxos/seedvault/core/backends/BackendProperties.kt b/core/src/main/java/org/calyxos/seedvault/core/backends/BackendProperties.kt index f4d4acc6f..1b31136d3 100644 --- a/core/src/main/java/org/calyxos/seedvault/core/backends/BackendProperties.kt +++ b/core/src/main/java/org/calyxos/seedvault/core/backends/BackendProperties.kt @@ -5,10 +5,10 @@ package org.calyxos.seedvault.core.backends -import android.annotation.WorkerThread import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET +import androidx.annotation.WorkerThread import at.bitfire.dav4jvm.exception.HttpException import java.io.IOException diff --git a/core/src/main/java/org/calyxos/seedvault/core/backends/saf/SafBackend.kt b/core/src/main/java/org/calyxos/seedvault/core/backends/saf/SafBackend.kt index bf7313372..028c521e9 100644 --- a/core/src/main/java/org/calyxos/seedvault/core/backends/saf/SafBackend.kt +++ b/core/src/main/java/org/calyxos/seedvault/core/backends/saf/SafBackend.kt @@ -29,7 +29,6 @@ import org.calyxos.seedvault.core.backends.FileHandle import org.calyxos.seedvault.core.backends.FileInfo import org.calyxos.seedvault.core.backends.LegacyAppBackupFile import org.calyxos.seedvault.core.backends.TopLevelFolder -import org.calyxos.seedvault.core.getBackendContext import java.io.IOException import java.io.InputStream import java.io.OutputStream @@ -41,17 +40,13 @@ internal const val ROOT_ID_DEVICE = "primary" private const val DEBUG_LOG = true public class SafBackend( - private val appContext: Context, + private val context: Context, private val safProperties: SafProperties, root: String = DIRECTORY_ROOT, ) : Backend { private val log = KotlinLogging.logger {} - /** - * Attention: This context might be from a different user. Use with care. - */ - private val context: Context get() = appContext.getBackendContext { safProperties.isUsb } private val cache = DocumentFileCache(context, safProperties.getDocumentFile(context), root) override suspend fun test(): Boolean { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c4299fc03..e4c40d107 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,10 @@ dokka = "1.9.20" # Dokka has no releases after 1.9.20 # Lint versions lint-rules = { strictly = "0.1.0" } +# Logging libs (check versions at /libs) +logging = { strictly = "6.0.3" } +slf4j-api = { strictly = "2.0.16" } + # Google versions # https://android.googlesource.com/platform/external/protobuf/+/refs/tags/android-15.0.0_r1/java/pom.xml#7 protobuf = { strictly = "3.21.12" } @@ -74,6 +78,9 @@ androidx-documentfile = { strictly = "1.1.0-alpha01" } # 1.1.0-alpha02 in AOSP b # https://android.googlesource.com/platform/prebuilts/sdk/+/android-15.0.0_r1/current/androidx/m2repository/androidx/work/work-runtime-ktx?autodive=0 androidx-work-runtime = { strictly = "2.10.0-alpha02" } +# https://android.googlesource.com/platform/external/okio/+/refs/tags/android-14.0.0_r53/CHANGELOG.md +squareup-okio = { strictly = "3.7.0" } + [libraries] # Kotlin standard dependencies kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } @@ -105,6 +112,10 @@ androidx-documentfile = { module = "androidx.documentfile:documentfile", version androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work-runtime" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } +squareup-okio = { module= "com.squareup.okio:okio", version.ref = "squareup-okio" } +kotlin-logging = { module = "io.github.oshai:kotlin-logging-jvm", version.ref = "logging" } +slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j-api" } + [bundles] kotlin = ["kotlin-stdlib", "kotlin-stdlib-jdk8", "kotlin-stdlib-common"] coroutines = ["kotlinx-coroutines-core-jvm", "kotlinx-coroutines-android"] diff --git a/libs/Android.bp b/libs/Android.bp index 33f511014..8a9c8e65c 100644 --- a/libs/Android.bp +++ b/libs/Android.bp @@ -8,3 +8,15 @@ java_import { jars: ["kotlin-bip39-jvm-1.0.6.jar"], sdk_version: "current", } + +java_import { + name: "seedvault-lib-kotlin-logging-jvm", + jars: ["kotlin-logging-jvm-6.0.3.jar"], + sdk_version: "current", +} + +java_import { + name: "seedvault-lib-slf4j-api", + jars: ["slf4j-api-2.0.16.jar"], + sdk_version: "current", +} diff --git a/libs/dav4jvm/Android.bp b/libs/dav4jvm/Android.bp index 660926629..ea70b04be 100644 --- a/libs/dav4jvm/Android.bp +++ b/libs/dav4jvm/Android.bp @@ -14,9 +14,3 @@ java_import { jars: ["okhttp-4.12.0.jar"], sdk_version: "current", } - -java_import { - name: "seedvault-lib-okio", - jars: ["okio-jvm-3.7.0.jar"], - sdk_version: "current", -} diff --git a/libs/dav4jvm/okio-jvm-3.7.0.jar b/libs/dav4jvm/okio-jvm-3.7.0.jar deleted file mode 100644 index 8da081a91..000000000 Binary files a/libs/dav4jvm/okio-jvm-3.7.0.jar and /dev/null differ diff --git a/libs/kotlin-logging-jvm-6.0.3.jar b/libs/kotlin-logging-jvm-6.0.3.jar new file mode 100644 index 000000000..b9f78839b Binary files /dev/null and b/libs/kotlin-logging-jvm-6.0.3.jar differ diff --git a/libs/slf4j-api-2.0.16.jar b/libs/slf4j-api-2.0.16.jar new file mode 100644 index 000000000..cbb5448d0 Binary files /dev/null and b/libs/slf4j-api-2.0.16.jar differ diff --git a/storage/lib/Android.bp b/storage/lib/Android.bp index d28d5c877..2cac46ca1 100644 --- a/storage/lib/Android.bp +++ b/storage/lib/Android.bp @@ -19,6 +19,7 @@ android_library { local_include_dirs: ["src/main/proto"], }, static_libs: [ + "seedvault-lib-core", "seedvault-lib-tink-android", "libprotobuf-java-lite", "androidx.core_core-ktx", diff --git a/storage/lib/build.gradle.kts b/storage/lib/build.gradle.kts index 49851eec9..5ada1faa4 100644 --- a/storage/lib/build.gradle.kts +++ b/storage/lib/build.gradle.kts @@ -94,9 +94,6 @@ dependencies { implementation(libs.androidx.room.runtime) implementation(libs.google.protobuf.javalite) implementation(libs.google.tink.android) - // TODO include via gradle and AOSP - // https://android.googlesource.com/platform/external/okio/+/refs/tags/android-14.0.0_r53/CHANGELOG.md - implementation(fileTree("${rootProject.rootDir}/libs/dav4jvm").include("okio-jvm-3.7.0.jar")) ksp(group = "androidx.room", name = "room-compiler", version = libs.versions.room.get()) lintChecks(libs.thirdegg.lint.rules)