Include user profile name in backup name
so it is easier to identify the right backup if more users backup to the same storage medium. Change-Id: I56fa93899da3764e20b6aee40adfd52722a05a9f
This commit is contained in:
parent
6e63d9bac0
commit
87db20e45f
5 changed files with 65 additions and 2 deletions
|
@ -46,6 +46,7 @@ It uses the same internal APIs as `adb backup` which is deprecated and thus need
|
|||
* `android.permission.MANAGE_USB` to access the serial number of USB mass storage devices.
|
||||
* `android.permission.WRITE_SECURE_SETTINGS` to change system backup settings and enable call log backup.
|
||||
* `android.permission.QUERY_ALL_PACKAGES` to get information about all installed apps for backup.
|
||||
* `android.permission.QUERY_USERS` to get the name of the user profile that gets backed up.
|
||||
* `android.permission.INSTALL_PACKAGES` to re-install apps when restoring from backup.
|
||||
* `android.permission.MANAGE_EXTERNAL_STORAGE` to backup and restore files from device storage.
|
||||
* `android.permission.ACCESS_MEDIA_LOCATION` to backup original media files e.g. without stripped EXIF metadata.
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
android:name="android.permission.READ_LOGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<!-- Used to get the name of the current profile -->
|
||||
<uses-permission android:name="android.permission.QUERY_USERS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<!-- Used for periodic storage backups -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@ package com.stevesoltys.seedvault.metadata
|
|||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.os.Build
|
||||
import android.os.UserManager
|
||||
import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
|
@ -67,7 +70,16 @@ internal class MetadataManager(
|
|||
fun onDeviceInitialization(token: Long) {
|
||||
val salt = crypto.getRandomBytes(METADATA_SALT_SIZE).encodeBase64()
|
||||
modifyCachedMetadata {
|
||||
metadata = BackupMetadata(token = token, salt = salt)
|
||||
val userName = getUserName()
|
||||
metadata = BackupMetadata(
|
||||
token = token,
|
||||
salt = salt,
|
||||
deviceName = if (userName == null) {
|
||||
"${Build.MANUFACTURER} ${Build.MODEL}"
|
||||
} else {
|
||||
"${Build.MANUFACTURER} ${Build.MODEL} - $userName"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,4 +309,12 @@ internal class MetadataManager(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getUserName(): String? {
|
||||
val perm = "android.permission.QUERY_USERS"
|
||||
return if (context.checkSelfPermission(perm) == PERMISSION_GRANTED) {
|
||||
val userManager = context.getSystemService(UserManager::class.java)
|
||||
userManager.userName
|
||||
} else null
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import android.content.pm.ApplicationInfo
|
|||
import android.content.pm.ApplicationInfo.FLAG_ALLOW_BACKUP
|
||||
import android.content.pm.ApplicationInfo.FLAG_SYSTEM
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.UserManager
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.stevesoltys.seedvault.Clock
|
||||
import com.stevesoltys.seedvault.TestApp
|
||||
|
@ -94,12 +96,16 @@ class MetadataManagerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `test onDeviceInitialization()`() {
|
||||
fun `test onDeviceInitialization() without user permission`() {
|
||||
every { clock.time() } returns time
|
||||
every { crypto.getRandomBytes(METADATA_SALT_SIZE) } returns saltBytes
|
||||
expectReadFromCache()
|
||||
expectModifyMetadata(initialMetadata)
|
||||
|
||||
every {
|
||||
context.checkSelfPermission("android.permission.QUERY_USERS")
|
||||
} returns PackageManager.PERMISSION_DENIED
|
||||
|
||||
manager.onDeviceInitialization(token)
|
||||
|
||||
assertEquals(token, manager.getBackupToken())
|
||||
|
@ -111,6 +117,37 @@ class MetadataManagerTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test onDeviceInitialization() with user permission`() {
|
||||
val userManager: UserManager = mockk()
|
||||
val userName = getRandomString()
|
||||
val newMetadata = initialMetadata.copy(
|
||||
deviceName = initialMetadata.deviceName + " - $userName",
|
||||
)
|
||||
|
||||
every { clock.time() } returns time
|
||||
every { crypto.getRandomBytes(METADATA_SALT_SIZE) } returns saltBytes
|
||||
expectReadFromCache()
|
||||
expectModifyMetadata(newMetadata)
|
||||
|
||||
every {
|
||||
context.checkSelfPermission("android.permission.QUERY_USERS")
|
||||
} returns PackageManager.PERMISSION_GRANTED
|
||||
every { context.getSystemService(UserManager::class.java) } returns userManager
|
||||
every { userManager.userName } returns userName
|
||||
|
||||
manager.onDeviceInitialization(token)
|
||||
|
||||
assertEquals(token, manager.getBackupToken())
|
||||
assertEquals(0L, manager.getLastBackupTime())
|
||||
|
||||
verify {
|
||||
cacheInputStream.close()
|
||||
cacheOutputStream.close()
|
||||
userManager.userName
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test onApkBackedUp() with no prior package metadata`() {
|
||||
val packageMetadata = PackageMetadata(
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<permission name="android.permission.MANAGE_USB"/>
|
||||
<permission name="android.permission.INSTALL_PACKAGES"/>
|
||||
<permission name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
|
||||
<permission name="android.permission.QUERY_USERS" />
|
||||
<permission name="android.permission.READ_LOGS"/>
|
||||
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
|
||||
<permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
|
|
Loading…
Reference in a new issue