Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App backup format v2 with compression and deduplication #750

Merged
merged 60 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
0ae1f0c
fix broken link in files backup docs
grote Jul 1, 2024
75797f9
add readme for app dedup research
grote Jun 27, 2024
b2307d9
Add protobuf definitions for snapshot
grote Jul 11, 2024
cb68f75
remove kotlin protobuf as its not in aosp
grote Aug 30, 2024
d2df088
Add zstd-jni library
grote Aug 30, 2024
c19787a
Prepare backends for new app backup repository
grote Sep 3, 2024
e6905c0
Move tink library into core module and expose via CoreCrypto
grote Sep 3, 2024
1efa8e8
Add prototype plumbing for new v2 app backup
grote Sep 6, 2024
e17c988
Back up app icons in new v2 format
grote Sep 6, 2024
897ae48
Back up app APKs in new v2 format
grote Sep 6, 2024
8ce79f4
Add protobuf-kotlin-lite and use new builders
grote Sep 6, 2024
83708d9
Prepare restore backup loading for v2
grote Sep 9, 2024
7c7ea5f
Full backup and restore using v2
grote Sep 6, 2024
c2ad309
K/V backup and restore using v2
grote Sep 10, 2024
7f9e84f
Stop writing out old metadata to backend
grote Sep 11, 2024
3c4b4f7
Remove hack of @pm@ backup when initializing transport
grote Sep 11, 2024
cacea88
Simplify transport init and token handling
grote Sep 11, 2024
5b567c7
Also snapshot unchanged APKs
grote Sep 11, 2024
952cdec
Fully implement BlobCache
grote Sep 12, 2024
bfa17fa
Fully implement SnapshotManager
grote Sep 12, 2024
a268116
Remove warnings when choosing backup location in UI
grote Sep 13, 2024
237fd68
Clean up metadata as it lost most of its importance
grote Sep 13, 2024
dd5180f
Polish BlobCreator and extend its test
grote Sep 13, 2024
538d794
Don't uninstall the app and clear data after instrumentation tests
grote Sep 13, 2024
52f528d
Fully implement BackupReceiver and write tests
grote Sep 13, 2024
f188230
Add padding to all blobs using the Padmé algorithm
grote Sep 16, 2024
463fc33
Log memory and when system calls App#onTrimMemory()
grote Sep 16, 2024
7702fb7
Polish SnapshotCreator and write tests
grote Sep 16, 2024
32e116f
Polish AppBackupManager and write tests
grote Sep 16, 2024
307ccf5
Move new classes to repo package
grote Sep 17, 2024
a1baa6f
Implement pruning of old snapshots and unused blobs
grote Sep 17, 2024
fe8d458
Always use SnapshotManager to load snapshots to benefit from cache
grote Sep 17, 2024
9de1d24
Remove D2D setting, it is now always on
grote Sep 17, 2024
62991ed
Move app backup to expert settings
grote Sep 17, 2024
20ea0b3
Delete repo and exit process when key changes
grote Sep 18, 2024
176a703
Offer option to recycle backup after restoring
grote Sep 18, 2024
03d2946
Remove setting for unlimited quota
grote Sep 18, 2024
83fd0ba
Upgrade all the binary dependencies we include
grote Sep 18, 2024
1aa5c68
Add RestoreV1IntegrationTest to ensure we can still restore v1 backup
grote Sep 19, 2024
1e5a4de
Clean up libraries, move to where they are included
grote Sep 23, 2024
5c75574
Use cached snapshots for auto-restore to save time
grote Sep 23, 2024
7b0e02c
Clean up code after refactorings
grote Sep 23, 2024
e602bbe
Adapt reuse backup screen after designer input
grote Sep 24, 2024
8d949e2
Support adb shell bmgr backupnow
grote Sep 25, 2024
b4c8427
Update UI state for some system apps if they have NO_DATA
grote Sep 25, 2024
eea65d4
do scheduling migration before strict mode
grote Sep 27, 2024
751504c
improve local metadata handling
grote Sep 27, 2024
f7354a3
Show when launchable system apps do not allow backup
grote Sep 27, 2024
b7b07d0
Fix recovery code keyboard input for Android 15
grote Sep 27, 2024
84dc13d
Split up success and error notification
grote Sep 27, 2024
7696b88
Improve RestoreSet display
grote Sep 30, 2024
11270ff
Reset latest snapshot to avoid it getting stale
grote Oct 1, 2024
f845158
Minor improvements for app restore
grote Oct 2, 2024
c09ea7c
Use BackupManagerMonitor to handle K/V with no data changed
grote Oct 1, 2024
682afa1
Try to recover data for force stopped apps from latest snapshot
grote Oct 3, 2024
9422d0d
Encode icons in PNG, because JPEG doesn't support transparency
grote Oct 3, 2024
14775b5
Check that exceptions from file loading get caught
grote Oct 7, 2024
9339f9f
when cached snapshot is corrupted fall back to loading from backend
grote Oct 10, 2024
16c00be
remove corrupted snapshots when pruning
grote Oct 10, 2024
2d47aa3
don't crash in BackupMonitor when there is no packageName
grote Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ echo "Installing Seedvault app..."
./gradlew --stacktrace :app:installDebugAndroidTest
sleep 60

D2D_BACKUP_TEST=$1

large_test_exit_code=0
./gradlew --stacktrace -Pinstrumented_test_size=large -Pd2d_backup_test="$D2D_BACKUP_TEST" :app:connectedAndroidTest || large_test_exit_code=$?
./gradlew --stacktrace -Pinstrumented_test_size=large :app:connectedAndroidTest || large_test_exit_code=$?

adb pull /sdcard/seedvault_test_results

Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ jobs:
matrix:
android_target: [ 34 ]
emulator_type: [ aosp_atd ]
d2d_backup_test: [ true, false ]
steps:
- name: Checkout Code
uses: actions/checkout@v3
Expand Down Expand Up @@ -53,7 +52,7 @@ jobs:
disable-animations: true
script: |
./app/development/scripts/provision_emulator.sh "test" "system-images;android-${{ matrix.android_target }};${{ matrix.emulator_type }};x86_64"
./.github/scripts/run_tests.sh ${{ matrix.d2d_backup_test }}
./.github/scripts/run_tests.sh

- name: Upload test results
if: always()
Expand Down
7 changes: 1 addition & 6 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 19 additions & 3 deletions Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@ android_app {
srcs: [
"app/src/main/java/**/*.kt",
"app/src/main/java/**/*.java",
"app/src/main/proto/*.proto",
// as of Android 15, there is no way to pass --kotlin_out to aprotoc compiler
"app/build/generated/source/proto/debug/kotlin/com/stevesoltys/seedvault/proto/*.kt",
],
resource_dirs: [
"app/src/main/res",
],
asset_dirs: [
"app/src/main/assets"
],
proto: {
type: "lite",
local_include_dirs: ["app/src/main/proto"],
},
static_libs: [
"kotlin-stdlib-jdk8",
"libprotobuf-java-lite",
"androidx.core_core-ktx",
"androidx.fragment_fragment-ktx",
"androidx.activity_activity-ktx",
Expand All @@ -26,6 +37,13 @@ android_app {
"com.google.android.material_material",
"kotlinx-coroutines-android",
"kotlinx-coroutines-core",
"seedvault-lib-kotlin-logging-jvm",
// app backup related libs
"seedvault-lib-protobuf-kotlin-lite",
"seedvault-logback-android",
"seedvault-lib-chunker",
"seedvault-lib-zstd-jni",
"okio-lib",
// our own gradle module libs
"seedvault-lib-core",
"seedvault-lib-storage",
Expand All @@ -34,10 +52,8 @@ android_app {
"seedvault-lib-koin-android",
// bip39
"seedvault-lib-kotlin-bip39",
// WebDAV
"seedvault-lib-dav4jvm",
"seedvault-lib-okhttp",
],
use_embedded_native_libs: true,
manifest: "app/src/main/AndroidManifest.xml",

platform_apis: true,
Expand Down
44 changes: 38 additions & 6 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
// SPDX-License-Identifier: Apache-2.0
//

import com.google.protobuf.gradle.id
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import java.io.ByteArrayOutputStream

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.google.protobuf)
}

val gitDescribe = {
Expand Down Expand Up @@ -37,9 +39,6 @@ android {

testInstrumentationRunnerArguments["size"] = testSize
}

val d2dBackupTest = project.findProperty("d2d_backup_test")?.toString() ?: "true"
testInstrumentationRunnerArguments["d2d_backup_test"] = d2dBackupTest
}

signingConfigs {
Expand Down Expand Up @@ -93,6 +92,30 @@ android {
}
}

protobuf {
protoc {
artifact = if ("aarch64" == System.getProperty("os.arch")) {
// mac m1
"com.google.protobuf:protoc:${libs.versions.protobuf.get()}:osx-x86_64"
} else {
// other
"com.google.protobuf:protoc:${libs.versions.protobuf.get()}"
}
}
generateProtoTasks {
all().forEach { task ->
task.plugins {
id("java") {
option("lite")
}
id("kotlin") {
option("lite")
}
}
}
}
}

lint {
abortOnError = true

Expand Down Expand Up @@ -132,7 +155,10 @@ dependencies {
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.google.material)

implementation(libs.google.protobuf.javalite)
implementation(libs.google.tink.android)
implementation(libs.kotlin.logging)
implementation(libs.squareup.okio)

/**
* Storage Dependencies
Expand All @@ -151,9 +177,13 @@ dependencies {
implementation(fileTree("${rootProject.rootDir}/libs/koin-android").include("*.jar"))
implementation(fileTree("${rootProject.rootDir}/libs/koin-android").include("*.aar"))

implementation(fileTree("${rootProject.rootDir}/libs").include("kotlin-bip39-jvm-1.0.6.jar"))

implementation(fileTree("${rootProject.rootDir}/libs/dav4jvm").include("*.jar"))
implementation(
fileTree("${rootProject.rootDir}/libs").include("protobuf-kotlin-lite-3.21.12.jar")
)
implementation(fileTree("${rootProject.rootDir}/libs").include("seedvault-chunker-0.1.jar"))
implementation(fileTree("${rootProject.rootDir}/libs").include("zstd-jni-1.5.6-5.aar"))
implementation(fileTree("${rootProject.rootDir}/libs").include("kotlin-bip39-jvm-1.0.8.jar"))
implementation(fileTree("${rootProject.rootDir}/libs").include("logback-android-3.0.0.aar"))

/**
* Test Dependencies (do not concern the AOSP build)
Expand All @@ -163,6 +193,7 @@ dependencies {
// anything less than 'implementation' fails tests run with gradlew
testImplementation(aospLibs)
testImplementation("androidx.test.ext:junit:1.1.5")
testImplementation("org.slf4j:slf4j-simple:2.0.3")
testImplementation("org.robolectric:robolectric:4.12.2")
testImplementation("org.hamcrest:hamcrest:2.2")
testImplementation("org.junit.jupiter:junit-jupiter-api:${libs.versions.junit5.get()}")
Expand All @@ -173,6 +204,7 @@ dependencies {
)
testImplementation("app.cash.turbine:turbine:1.0.0")
testImplementation("org.bitcoinj:bitcoinj-core:0.16.2")
testImplementation("com.github.luben:zstd-jni:1.5.6-5")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${libs.versions.junit5.get()}")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:${libs.versions.junit5.get()}")

Expand Down
Loading
Loading