Skip to content

Commit

Permalink
Merge tag '14-4.1' of https://github.com/seedvault-app/seedvault into…
Browse files Browse the repository at this point in the history
… HEAD

SeedVault 14-4.1

* It is now possible to restore after setting up a profile
* It is now possible to select what to restore (e.g. apps, files...)
* Automatic backup scheduling can now be modified by the user
* Native support for WebDAV
* Support for RoundSync (if enabled by the OS)
* Now in Material 3
* Name of profile is now shown when selecting a backup to restore
* Already installed apps are not reinstalled anymore
* Already stored files do not create duplicates anymore
* Respect policy when the installation of apps is disallowed
* Storage backup is now beta instead of experimental
* D2D is now alpha instead of experimental
* Various corrections to the UI

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEE8LiYseXDVwsHMtSKo5wwJqfeYAEFAmba/IcACgkQo5wwJqfe
# YAHJQBAAl42E3TsH4p6o+VwB+VtWIYU6is4Vi/7gQr2ZiKYTito06YgXIzXZRYIk
# Wd6142j7b9WKuuXQ/9GRxfjUrLvEmrfpq3ykL+N8q5TKXBcJNW6Cy03kdERhT0PH
# sVVYsVmNsi7Zd//sbOiWRsJsfPkvQztbdr7zyKj4IWzhDDsP/wRN++2mnq+PaPQN
# mFkc7c3PckUpdCwFPYeRT+cZBz2OG6hnmzRjzs96zOBX3yuWPsukqh7M0ZlJxiF1
# 74metuUgMlVReomBKNkBgTRtcQ0NTOTlqgXohcaVXFPllW/HaA/gIxdd1Z3UW/Tr
# 0t4Zb6Az1Dm2n/S/sUXwBjStWLKoGqcw/4pFx33bq27k2MFGM4t9U/yWvOFXNht2
# 4C3pgGdfDP4Qq3YNJuq0r46F3mTjT6uLFfAAf+DGSoRJ+vuHrXofRCgta3Kol9yi
# 4dMc1F0EzToL9EZMXicJAuIenEen+OdPPKTIQuBb7CSsHWeJP4TiFnrsK/juUjrJ
# gyq6I5C90brvkffVEKkH1/h+h50NEdgjusFexHBe6fi4XIlbauELs55uviuBkGQf
# FyAEOVouWvHd184Jix1mkcDq7jRC4tK+xQecAWjm2LHi6TMOqGqJBKoZbP5FSdkQ
# 9HMocyeuRe5Cp8wHlLMEKwIbjNf5P2swouk9u92Xzhrp+AHMrrY=
# =Oqpw
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 06 Sep 2024 06:28:47 PM IST
# gpg:                using RSA key F0B898B1E5C3570B0732D48AA39C3026A7DE6001
# gpg: Good signature from "Chirayu Desai <chirayudesai1@gmail.com>" [ultimate]
# gpg:                 aka "Chirayu Desai <chirayu@calyxinstitute.org>" [ultimate]
# gpg:                 aka "Chirayu Desai <chirayu@cdesai.in>" [ultimate]

* tag '14-4.1' of https://github.com/seedvault-app/seedvault: (93 commits)
  drawable: Use text color for system icons
  Fix retries: don't upload metadata three times
  Show app is in progress before we download APKs
  Don't allow app selection toggles before icons have loaded
  Bump to 14-4.1 - many cool things :D
  Don't use Context#startForegroundService() because we may get killed
  Fix joining string for file selection
  Restore files ownership only when file isn't pending anymore
  make file restore numbers add up by showing duplicates and errors
  don't restore files that still exist unchanged
  declare foreground service type also when starting service
  store owner of media file and whether it is marked favorite
  Start a foreground service during restore
  Don't back up to USB, if backup disabled
  Allow restore whenever the user feels like it
  Disable auto-restore during install, if it was on
  Move Settings.Secure backup flags into BackupStateManager
  Fix app selection when restoring after SUW
  Don't re-install apps that are already installed
  Fix back navigation when FirstRunFragment is shown
  ...

Change-Id: If29925b2e148d56801a094f4801196aa33ec8801
  • Loading branch information
chirayudesai committed Sep 11, 2024
2 parents 6d23272 + 10f9f8e commit 7978494
Show file tree
Hide file tree
Showing 166 changed files with 4,547 additions and 1,255 deletions.
17 changes: 4 additions & 13 deletions .github/scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@
# SPDX-License-Identifier: Apache-2.0
#

adb root
sleep 5
adb remount
echo "Disable auto-restore"
adb shell bmgr autorestore false

echo "Installing Seedvault app..."
adb shell mkdir -p /system/priv-app/Seedvault
adb push app/build/outputs/apk/release/app-release.apk /system/priv-app/Seedvault/Seedvault.apk

echo "Installing Seedvault permissions..."
adb push permissions_com.stevesoltys.seedvault.xml /system/etc/permissions/privapp-permissions-seedvault.xml
adb push allowlist_com.stevesoltys.seedvault.xml /system/etc/sysconfig/allowlist-seedvault.xml

echo "Setting Seedvault transport..."
sleep 10
adb shell bmgr transport com.stevesoltys.seedvault.transport.ConfigurableBackupTransport
./gradlew --stacktrace :app:installDebugAndroidTest
sleep 60

D2D_BACKUP_TEST=$1

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrency:

jobs:
instrumentation_tests:
runs-on: macos-11
runs-on: macos-12
if: github.repository == 'seedvault-app/seedvault'
timeout-minutes: 80
strategy:
Expand Down
1 change: 1 addition & 0 deletions .idea/dictionaries/user.xml

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

66 changes: 66 additions & 0 deletions .idea/runConfigurations/app.xml

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

15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## [14-4.1] - 2024-08-23
* It is now possible to restore after setting up a profile
* It is now possible to select what to restore (e.g. apps, files...)
* Automatic backup scheduling can now be modified by the user
* Native support for WebDAV
* Support for RoundSync (if enabled by the OS)
* Now in Material 3
* Name of profile is now shown when selecting a backup to restore
* Already installed apps are not reinstalled anymore
* Already stored files do not create duplicates anymore
* Respect policy when the installation of apps is disallowed
* Storage backup is now beta instead of experimental
* D2D is now alpha instead of experimental
* Various corrections to the UI

## [14-4.0] - 2024-01-24
* Add experimental support for forcing "D2D" transfer backups
* Pretend to be a device-to-device transfer to allow backing up many apps which prevent backup
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ If you are having an issue/question, please look at our [FAQ](https://github.com

## Requirements

SeedVault is developed alongwith AOSP releases
SeedVault is developed along with AOSP releases

We update it every time Google releases a new Android version, make any changes required for basic functionality, and any improvements possible through API changes in the OS.

Expand Down
8 changes: 5 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,11 @@ dependencies {
* in the top-level `libs` folder to reflect that.
* You can copy these libraries from ~/.gradle/caches/modules-2/files-2.1
*/
// later versions than 2.1.1 require newer kotlin version
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"))

// dav4jvm - later versions of okhttp need kotlin > 1.9.0
implementation(fileTree("${rootProject.rootDir}/libs/dav4jvm").include("*.jar"))

/**
Expand All @@ -176,11 +174,15 @@ dependencies {
// anything less than 'implementation' fails tests run with gradlew
testImplementation(aospLibs)
testImplementation("androidx.test.ext:junit:1.1.5")
testImplementation("org.robolectric:robolectric:4.10.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()}")
testImplementation("org.junit.jupiter:junit-jupiter-params:${libs.versions.junit5.get()}")
testImplementation("io.mockk:mockk:${libs.versions.mockk.get()}")
testImplementation(
"org.jetbrains.kotlinx:kotlinx-coroutines-test:${libs.versions.coroutines.get()}"
)
testImplementation("app.cash.turbine:turbine:1.0.0")
testImplementation("org.bitcoinj:bitcoinj-core:0.16.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${libs.versions.junit5.get()}")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:${libs.versions.junit5.get()}")
Expand Down
13 changes: 4 additions & 9 deletions app/development/scripts/install_app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ if [ -z "$ANDROID_HOME" ]; then
fi

SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
DEVELOPMENT_DIR=$SCRIPT_DIR/..
ROOT_PROJECT_DIR=$SCRIPT_DIR/../../..

EMULATOR_DEVICE_NAME=$($ANDROID_HOME/platform-tools/adb devices | grep emulator | cut -f1)
EMULATOR_DEVICE_NAME=$("$ANDROID_HOME"/platform-tools/adb devices | grep emulator | cut -f1)

if [ -z "$EMULATOR_DEVICE_NAME" ]; then
echo "Emulator device name not found"
Expand All @@ -29,13 +28,9 @@ $ADB remount # remount /system as writable

echo "Installing Seedvault app..."
$ADB shell mkdir -p /system/priv-app/Seedvault
$ADB push $ROOT_PROJECT_DIR/app/build/outputs/apk/release/app-release.apk /system/priv-app/Seedvault/Seedvault.apk
$ADB push "$ROOT_PROJECT_DIR"/app/build/outputs/apk/release/app-release.apk /system/priv-app/Seedvault/Seedvault.apk

echo "Installing Seedvault permissions..."
$ADB push $ROOT_PROJECT_DIR/permissions_com.stevesoltys.seedvault.xml /system/etc/permissions/privapp-permissions-seedvault.xml
$ADB push $ROOT_PROJECT_DIR/allowlist_com.stevesoltys.seedvault.xml /system/etc/sysconfig/allowlist-seedvault.xml
$ADB shell am force-stop com.stevesoltys.seedvault
$ADB push "$ROOT_PROJECT_DIR"/permissions_com.stevesoltys.seedvault.xml /system/etc/permissions/privapp-permissions-seedvault.xml
$ADB push "$ROOT_PROJECT_DIR"/allowlist_com.stevesoltys.seedvault.xml /system/etc/sysconfig/allowlist-seedvault.xml
$ADB shell am broadcast -a android.intent.action.BOOT_COMPLETED

echo "Setting Seedvault transport..."
$ADB shell bmgr transport com.stevesoltys.seedvault.transport.ConfigurableBackupTransport
22 changes: 9 additions & 13 deletions app/development/scripts/provision_emulator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,23 @@ EMULATOR_NAME=$1
SYSTEM_IMAGE=$2

SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
DEVELOPMENT_DIR=$SCRIPT_DIR/..
ROOT_PROJECT_DIR=$SCRIPT_DIR/../../..

echo "Downloading system image..."
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "$SYSTEM_IMAGE"
yes | "$ANDROID_HOME"/cmdline-tools/latest/bin/sdkmanager --install "$SYSTEM_IMAGE"

# create AVD if it doesn't exist
if $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager list avd | grep -q "$EMULATOR_NAME"; then
if "$ANDROID_HOME"/cmdline-tools/latest/bin/avdmanager list avd | grep -q "$EMULATOR_NAME"; then
echo "AVD already exists. Skipping creation."
else
echo "Creating AVD..."
echo 'no' | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n "$EMULATOR_NAME" -k "$SYSTEM_IMAGE"
echo 'no' | "$ANDROID_HOME"/cmdline-tools/latest/bin/avdmanager create avd -n "$EMULATOR_NAME" -k "$SYSTEM_IMAGE"
sleep 1
fi

EMULATOR_DEVICE_NAME=$($ANDROID_HOME/platform-tools/adb devices | grep emulator | cut -f1)
EMULATOR_DEVICE_NAME=$("$ANDROID_HOME"/platform-tools/adb devices | grep emulator | cut -f1)

if [ -z "$EMULATOR_DEVICE_NAME" ]; then
$SCRIPT_DIR/start_emulator.sh "$EMULATOR_NAME"
"$SCRIPT_DIR"/start_emulator.sh "$EMULATOR_NAME"
fi

# wait for emulator device to appear with 180 second timeout
Expand All @@ -47,7 +45,7 @@ echo "Waiting for emulator device..."
for i in {1..180}; do
if [ -z "$EMULATOR_DEVICE_NAME" ]; then
sleep 1
EMULATOR_DEVICE_NAME=$($ANDROID_HOME/platform-tools/adb devices | grep emulator | cut -f1)
EMULATOR_DEVICE_NAME=$("$ANDROID_HOME"/platform-tools/adb devices | grep emulator | cut -f1)
else
break
fi
Expand All @@ -73,16 +71,14 @@ $ADB reboot # need to reboot first time we remount
$ADB wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'

echo "Provisioning emulator for Seedvault..."
$SCRIPT_DIR/install_app.sh
"$SCRIPT_DIR"/install_app.sh

echo "Rebooting emulator..."
$ADB reboot
$ADB wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'

echo "Setting backup transport to Seedvault..."
$ADB shell bmgr enable true
sleep 5
$ADB shell bmgr transport com.stevesoltys.seedvault.transport.ConfigurableBackupTransport
echo "Disabling backup..."
$ADB shell bmgr enable false

echo "Downloading and extracting test backup to '/sdcard/seedvault_baseline'..."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,20 @@ class KoinInstrumentationTestApp : App() {

viewModel {
currentRestoreViewModel =
spyk(RestoreViewModel(context, get(), get(), get(), get(), get(), get(), get()))
spyk(
RestoreViewModel(
app = context,
settingsManager = get(),
keyManager = get(),
backupManager = get(),
restoreCoordinator = get(),
apkRestore = get(),
iconManager = get(),
storageBackup = get(),
pluginManager = get(),
fileSelectionManager = get(),
)
)
currentRestoreViewModel!!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ internal interface LargeRestoreTestBase : LargeTestBase {
backupListItem.clickAndWaitForNewWindow()
waitUntilIdle()

waitForAppSelectionLoaded()
// just tap next in app selection
appsSelectedButton.clickAndWaitForNewWindow()

waitForInstallResult()

if (someAppsNotInstalledText.exists()) {
Expand Down Expand Up @@ -104,13 +108,22 @@ internal interface LargeRestoreTestBase : LargeTestBase {
spyOnKVRestoreData(result)
}

private fun waitForAppSelectionLoaded() = runBlocking {
withContext(Dispatchers.Main) {
withTimeout(RESTORE_TIMEOUT) {
while (spyRestoreViewModel.selectedApps.value?.apps?.isNotEmpty() != true) {
delay(100)
}
}
}
waitUntilIdle()
}

private fun waitForInstallResult() = runBlocking {

withContext(Dispatchers.Main) {
withTimeout(RESTORE_TIMEOUT) {
while (spyRestoreViewModel.installResult.value == null ||
spyRestoreViewModel.nextButtonEnabled.value == false
) {
while (spyRestoreViewModel.installResult.value?.isFinished != true) {
delay(100)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ internal interface LargeTestBase : KoinComponent {
}

fun testResultFilename(testName: String): String {
val arguments = InstrumentationRegistry.getArguments()
val d2d = if (arguments.getString("d2d_backup_test") == "true") "d2d" else ""
val simpleDateFormat = SimpleDateFormat("yyyyMMdd_hhmmss")
val timeStamp = simpleDateFormat.format(Calendar.getInstance().time)
return "${timeStamp}_${testName.replace(" ", "_")}"
return "${timeStamp}_${d2d}_${testName.replace(" ", "_")}"
}

@OptIn(DelicateCoroutinesApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.junit.rules.TestName
import org.junit.runner.RunWith
import org.koin.core.component.KoinComponent
import java.io.File
import java.lang.Thread.sleep
import java.util.concurrent.atomic.AtomicBoolean

@RunWith(AndroidJUnit4::class)
Expand Down Expand Up @@ -44,6 +45,11 @@ internal abstract class SeedvaultLargeTest :
resetApplicationState()
clearTestBackups()

runCommand("bmgr enable true")
sleep(60_000)
runCommand("bmgr transport com.stevesoltys.seedvault.transport.ConfigurableBackupTransport")
sleep(60_000)

startRecordingTest(keepRecordingScreen, name.methodName)
restoreBaselineBackup()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package com.stevesoltys.seedvault.e2e.impl

import androidx.test.filters.LargeTest
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
import com.stevesoltys.seedvault.e2e.SeedvaultLargeTest
import com.stevesoltys.seedvault.e2e.SeedvaultLargeTestResult
import com.stevesoltys.seedvault.metadata.PackageState
Expand Down Expand Up @@ -127,17 +128,19 @@ internal class BackupRestoreTest : SeedvaultLargeTest() {
) {
// Assert all "key/value" restored data matches the backup data.
restore.kv.forEach { (pkg, kvData) ->
assert(backup.kv.containsKey(pkg)) {
"KV data for $pkg missing from backup."
}

kvData.forEach { (key, value) ->
assert(backup.kv[pkg]!!.containsKey(key)) {
"KV data for $pkg/$key exists in restore but is missing from backup."
if (pkg != MAGIC_PACKAGE_MANAGER) {
assert(backup.kv.containsKey(pkg)) {
"KV data for $pkg missing from backup."
}

assert(value.contentEquals(backup.kv[pkg]!![key]!!)) {
"KV data for $pkg/$key does not match."
kvData.forEach { (key, value) ->
assert(backup.kv[pkg]!!.containsKey(key)) {
"KV data for $pkg/$key exists in restore but is missing from backup."
}

assert(value.contentEquals(backup.kv[pkg]!![key]!!)) {
"KV data for $pkg/$key does not match."
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ object RestoreScreen : UiDeviceScreen<RestoreScreen>() {

val backupListItem = findObject { textContains("Last backup") }

val appsSelectedButton = findObject { text("Restore backup") }

val nextButton = findObject { text("Next") }

val finishButton = findObject { text("Finish") }
Expand Down
Loading

0 comments on commit 7978494

Please sign in to comment.