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 <[email protected]>" [ultimate]
# gpg:                 aka "Chirayu Desai <[email protected]>" [ultimate]
# gpg:                 aka "Chirayu Desai <[email protected]>" [ultimate]

* tag '14-4.1' of https://github.com/seedvault-app/seedvault: (33 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: I1f73d061d203925330c580eab5b3c87480f0a398
  • Loading branch information
chirayudesai committed Sep 11, 2024
2 parents 4dc4684 + 10f9f8e commit c906fd7
Show file tree
Hide file tree
Showing 88 changed files with 1,799 additions and 234 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class KoinInstrumentationTestApp : App() {
iconManager = get(),
storageBackup = get(),
pluginManager = get(),
fileSelectionManager = get(),
)
)
currentRestoreViewModel!!
Expand Down
8 changes: 7 additions & 1 deletion app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
<activity
android:name="com.stevesoltys.seedvault.settings.SettingsActivity"
android:exported="true"
tools:remove="android:permission" />
tools:remove="android:permission">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name="com.stevesoltys.seedvault.restore.RestoreActivity"
android:exported="true"
Expand Down
2 changes: 0 additions & 2 deletions app/src/debug/res/values/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<bool name="show_restore_in_settings">true</bool>

<string-array name="storage_authority_whitelist">
<item>com.android.externalstorage.documents</item>
<item>org.nextcloud.documents</item>
Expand Down
26 changes: 10 additions & 16 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.stevesoltys.seedvault"
android:versionCode="34040000"
android:versionName="14-4.0">
android:versionCode="34040010"
android:versionName="14-4.1">
<!--
The version code is the targeted SDK_VERSION plus 6 digits for our own version code.
The version name is the targeted Android version followed by - and our own version name.
Expand Down Expand Up @@ -154,18 +154,6 @@
</intent-filter>
</receiver>

<receiver
android:name=".SecretCodeReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.telephony.action.SECRET_CODE" />
<!-- *#*#RESTORE#*#* -->
<data
android:host="7378673"
android:scheme="android_secret_code" />
</intent-filter>
</receiver>

<!-- Used by Workmanager to schedule our workers -->
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
Expand All @@ -177,13 +165,19 @@
android:exported="false"
android:label="BackupJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Does the actual backup work as a foreground service -->
<!-- Does app restore as a foreground service -->
<service
android:name=".restore.RestoreService"
android:exported="false"
android:foregroundServiceType="dataSync"
android:label="RestoreService" />
<!-- Does the actual file backup work as a foreground service -->
<service
android:name=".storage.StorageBackupService"
android:exported="false"
android:foregroundServiceType="dataSync"
android:label="BackupService" />
<!-- Does restore as a foreground service -->
<!-- Does file restore as a foreground service -->
<service
android:name=".storage.StorageRestoreService"
android:exported="false"
Expand Down
26 changes: 4 additions & 22 deletions app/src/main/java/com/stevesoltys/seedvault/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import android.os.ServiceManager.getService
import android.os.StrictMode
import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings
import androidx.work.ExistingPeriodicWorkPolicy.UPDATE
import androidx.work.WorkManager
import com.google.android.material.color.DynamicColors
Expand All @@ -28,16 +27,15 @@ import com.stevesoltys.seedvault.metadata.metadataModule
import com.stevesoltys.seedvault.plugins.StoragePluginManager
import com.stevesoltys.seedvault.plugins.saf.storagePluginModuleSaf
import com.stevesoltys.seedvault.plugins.webdav.storagePluginModuleWebDav
import com.stevesoltys.seedvault.restore.RestoreViewModel
import com.stevesoltys.seedvault.restore.install.installModule
import com.stevesoltys.seedvault.restore.restoreUiModule
import com.stevesoltys.seedvault.settings.AppListRetriever
import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.settings.SettingsViewModel
import com.stevesoltys.seedvault.storage.storageModule
import com.stevesoltys.seedvault.transport.TRANSPORT_ID
import com.stevesoltys.seedvault.transport.backup.backupModule
import com.stevesoltys.seedvault.transport.restore.restoreModule
import com.stevesoltys.seedvault.ui.files.FileSelectionViewModel
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
import com.stevesoltys.seedvault.ui.recoverycode.RecoveryCodeViewModel
import com.stevesoltys.seedvault.ui.storage.BackupStorageViewModel
Expand Down Expand Up @@ -97,20 +95,6 @@ open class App : Application() {
)
}
viewModel { RestoreStorageViewModel(this@App, get(), get(), get(), get()) }
viewModel {
RestoreViewModel(
app = this@App,
settingsManager = get(),
keyManager = get(),
backupManager = get(),
restoreCoordinator = get(),
apkRestore = get(),
iconManager = get(),
storageBackup = get(),
pluginManager = get(),
)
}
viewModel { FileSelectionViewModel(this@App, get()) }
}

override fun onCreate() {
Expand Down Expand Up @@ -155,13 +139,15 @@ open class App : Application() {
installModule,
storageModule,
workerModule,
restoreUiModule,
appModule
)

private val settingsManager: SettingsManager by inject()
private val metadataManager: MetadataManager by inject()
private val backupManager: IBackupManager by inject()
private val pluginManager: StoragePluginManager by inject()
private val backupStateManager: BackupStateManager by inject()

/**
* The responsibility for the current token was moved to the [SettingsManager]
Expand All @@ -182,7 +168,7 @@ open class App : Application() {
* Introduced in the first half of 2024 and can be removed after a suitable migration period.
*/
protected open fun migrateToOwnScheduling() {
if (!isFrameworkSchedulingEnabled()) { // already on own scheduling
if (!backupStateManager.isFrameworkSchedulingEnabled) { // already on own scheduling
// fix things for removable drive users who had a job scheduled here before
if (pluginManager.isOnRemovableDrive) AppBackupWorker.unschedule(applicationContext)
return
Expand All @@ -198,10 +184,6 @@ open class App : Application() {
}
}

private fun isFrameworkSchedulingEnabled(): Boolean = Settings.Secure.getInt(
contentResolver, Settings.Secure.BACKUP_SCHEDULING_ENABLED, 1
) == 1 // 1 means enabled which is the default

}

const val MAGIC_PACKAGE_MANAGER: String = PACKAGE_MANAGER_SENTINEL
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/stevesoltys/seedvault/BackupStateManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
package com.stevesoltys.seedvault

import android.content.Context
import android.provider.Settings
import android.provider.Settings.Secure.BACKUP_AUTO_RESTORE
import android.provider.Settings.Secure.BACKUP_SCHEDULING_ENABLED
import android.util.Log
import androidx.work.WorkInfo.State.RUNNING
import androidx.work.WorkManager
Expand All @@ -22,6 +25,7 @@ class BackupStateManager(
) {

private val workManager = WorkManager.getInstance(context)
private val contentResolver = context.contentResolver

val isBackupRunning: Flow<Boolean> = combine(
flow = ConfigurableBackupTransportService.isRunning,
Expand All @@ -37,4 +41,10 @@ class BackupStateManager(
appBackupRunning || filesBackupRunning || workInfoState == RUNNING
}

val isAutoRestoreEnabled: Boolean
get() = Settings.Secure.getInt(contentResolver, BACKUP_AUTO_RESTORE, 1) == 1

val isFrameworkSchedulingEnabled: Boolean
get() = Settings.Secure.getInt(contentResolver, BACKUP_SCHEDULING_ENABLED, 1) == 1

}
28 changes: 0 additions & 28 deletions app/src/main/java/com/stevesoltys/seedvault/SecretCodeReceiver.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package com.stevesoltys.seedvault

import android.app.backup.IBackupManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
Expand Down Expand Up @@ -37,6 +38,7 @@ class UsbIntentReceiver : UsbMonitor() {
// using KoinComponent would crash robolectric tests :(
private val settingsManager: SettingsManager by lazy { get().get() }
private val metadataManager: MetadataManager by lazy { get().get() }
private val backupManager: IBackupManager by lazy { get().get() }

override fun shouldMonitorStatus(context: Context, action: String, device: UsbDevice): Boolean {
if (action != ACTION_USB_DEVICE_ATTACHED) return false
Expand Down Expand Up @@ -67,8 +69,10 @@ class UsbIntentReceiver : UsbMonitor() {
// this starts an app backup afterwards
i.putExtra(EXTRA_START_APP_BACKUP, true)
startForegroundService(context, i)
} else {
} else if (backupManager.isBackupEnabled) {
AppBackupWorker.scheduleNow(context, reschedule = false)
} else {
Log.d(TAG, "Neither files nor app backup enabled, do nothing.")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.app.backup.IRestoreObserver
import android.app.backup.IRestoreSession
import android.app.backup.RestoreSet
import android.content.Context
import android.content.Intent
import android.os.RemoteException
import android.os.UserHandle
import android.util.Log
Expand Down Expand Up @@ -60,6 +61,7 @@ internal class AppDataRestoreManager(

private var session: IRestoreSession? = null
private val monitor = BackupMonitor()
private val foregroundServiceIntent = Intent(context, RestoreService::class.java)

private val mRestoreProgress = MutableLiveData(
LinkedList<AppRestoreResult>().apply {
Expand Down Expand Up @@ -120,6 +122,9 @@ internal class AppDataRestoreManager(
mRestoreBackupResult.postValue(
RestoreBackupResult(context.getString(R.string.restore_set_error))
)
} else {
// don't use startForeground(), because we may stop it sooner than the system likes
context.startService(foregroundServiceIntent)
}
}

Expand Down Expand Up @@ -208,6 +213,8 @@ internal class AppDataRestoreManager(
mRestoreProgress.postValue(list)

mRestoreBackupResult.postValue(result)

context.stopService(foregroundServiceIntent)
}

fun closeSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,6 @@ internal class AppSelectionAdapter(

fun bind(item: SelectableAppItem) {
v.background = clickableBackground
v.setOnClickListener {
checkBox.toggle()
}

checkBox.setOnCheckedChangeListener(null)
checkBox.isChecked = item.selected
Expand All @@ -155,6 +152,11 @@ internal class AppSelectionAdapter(
}
checkBox.visibility = if (item.hasIcon == null) INVISIBLE else VISIBLE
progressBar.visibility = if (item.hasIcon == null) VISIBLE else INVISIBLE
if (item.hasIcon == null) {
v.setOnClickListener(null)
} else v.setOnClickListener {
checkBox.toggle()
}

val isSpecial = item.metadata.isInternalSystem
appIcon.scaleType = FIT_CENTER
Expand Down
Loading

0 comments on commit c906fd7

Please sign in to comment.