Polish SnapshotCreator and write tests

This commit is contained in:
Torsten Grote 2024-09-16 16:28:11 -03:00
parent 463fc33230
commit 7702fb7bd8
No known key found for this signature in database
GPG key ID: 3E5F77D92CF891FF
8 changed files with 252 additions and 120 deletions

View file

@ -74,7 +74,24 @@ public object SnapshotKt {
} }
/** /**
* <code>string androidId = 4;</code> * <code>string user = 4;</code>
*/
public var user: kotlin.String
@JvmName("getUser")
get() = _builder.getUser()
@JvmName("setUser")
set(value) {
_builder.setUser(value)
}
/**
* <code>string user = 4;</code>
*/
public fun clearUser() {
_builder.clearUser()
}
/**
* <code>string androidId = 5;</code>
*/ */
public var androidId: kotlin.String public var androidId: kotlin.String
@JvmName("getAndroidId") @JvmName("getAndroidId")
@ -84,14 +101,14 @@ public object SnapshotKt {
_builder.setAndroidId(value) _builder.setAndroidId(value)
} }
/** /**
* <code>string androidId = 4;</code> * <code>string androidId = 5;</code>
*/ */
public fun clearAndroidId() { public fun clearAndroidId() {
_builder.clearAndroidId() _builder.clearAndroidId()
} }
/** /**
* <code>uint32 sdkInt = 5;</code> * <code>uint32 sdkInt = 6;</code>
*/ */
public var sdkInt: kotlin.Int public var sdkInt: kotlin.Int
@JvmName("getSdkInt") @JvmName("getSdkInt")
@ -101,14 +118,14 @@ public object SnapshotKt {
_builder.setSdkInt(value) _builder.setSdkInt(value)
} }
/** /**
* <code>uint32 sdkInt = 5;</code> * <code>uint32 sdkInt = 6;</code>
*/ */
public fun clearSdkInt() { public fun clearSdkInt() {
_builder.clearSdkInt() _builder.clearSdkInt()
} }
/** /**
* <code>string androidIncremental = 6;</code> * <code>string androidIncremental = 7;</code>
*/ */
public var androidIncremental: kotlin.String public var androidIncremental: kotlin.String
@JvmName("getAndroidIncremental") @JvmName("getAndroidIncremental")
@ -118,14 +135,14 @@ public object SnapshotKt {
_builder.setAndroidIncremental(value) _builder.setAndroidIncremental(value)
} }
/** /**
* <code>string androidIncremental = 6;</code> * <code>string androidIncremental = 7;</code>
*/ */
public fun clearAndroidIncremental() { public fun clearAndroidIncremental() {
_builder.clearAndroidIncremental() _builder.clearAndroidIncremental()
} }
/** /**
* <code>bool d2d = 7;</code> * <code>bool d2d = 8;</code>
*/ */
public var d2D: kotlin.Boolean public var d2D: kotlin.Boolean
@JvmName("getD2D") @JvmName("getD2D")
@ -135,7 +152,7 @@ public object SnapshotKt {
_builder.setD2D(value) _builder.setD2D(value)
} }
/** /**
* <code>bool d2d = 7;</code> * <code>bool d2d = 8;</code>
*/ */
public fun clearD2D() { public fun clearD2D() {
_builder.clearD2D() _builder.clearD2D()
@ -148,7 +165,7 @@ public object SnapshotKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
public class AppsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() public class AppsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
public val apps: com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.App, AppsProxy> public val apps: com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.App, AppsProxy>
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -157,7 +174,7 @@ public object SnapshotKt {
_builder.getAppsMap() _builder.getAppsMap()
) )
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
@JvmName("putApps") @JvmName("putApps")
public fun com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.App, AppsProxy> public fun com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.App, AppsProxy>
@ -165,7 +182,7 @@ public object SnapshotKt {
_builder.putApps(key, value) _builder.putApps(key, value)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("setApps") @JvmName("setApps")
@ -175,7 +192,7 @@ public object SnapshotKt {
put(key, value) put(key, value)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("removeApps") @JvmName("removeApps")
@ -184,7 +201,7 @@ public object SnapshotKt {
_builder.removeApps(key) _builder.removeApps(key)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("putAllApps") @JvmName("putAllApps")
@ -193,7 +210,7 @@ public object SnapshotKt {
_builder.putAllApps(map) _builder.putAllApps(map)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 8;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.App&gt; apps = 9;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("clearApps") @JvmName("clearApps")
@ -209,7 +226,7 @@ public object SnapshotKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
public class IconChunkIdsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() public class IconChunkIdsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/** /**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
*/ */
public val iconChunkIds: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy> public val iconChunkIds: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -217,7 +234,7 @@ public object SnapshotKt {
_builder.getIconChunkIdsList() _builder.getIconChunkIdsList()
) )
/** /**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
* @param value The iconChunkIds to add. * @param value The iconChunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -225,7 +242,7 @@ public object SnapshotKt {
public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.add(value: com.google.protobuf.ByteString) { public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.add(value: com.google.protobuf.ByteString) {
_builder.addIconChunkIds(value) _builder.addIconChunkIds(value)
}/** }/**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
* @param value The iconChunkIds to add. * @param value The iconChunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -234,7 +251,7 @@ public object SnapshotKt {
public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.plusAssign(value: com.google.protobuf.ByteString) { public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.plusAssign(value: com.google.protobuf.ByteString) {
add(value) add(value)
}/** }/**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
* @param values The iconChunkIds to add. * @param values The iconChunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -242,7 +259,7 @@ public object SnapshotKt {
public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) { public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
_builder.addAllIconChunkIds(values) _builder.addAllIconChunkIds(values)
}/** }/**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
* @param values The iconChunkIds to add. * @param values The iconChunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -251,7 +268,7 @@ public object SnapshotKt {
public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) { public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
addAll(values) addAll(values)
}/** }/**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
* @param index The index to set the value at. * @param index The index to set the value at.
* @param value The iconChunkIds to set. * @param value The iconChunkIds to set.
*/ */
@ -260,7 +277,7 @@ public object SnapshotKt {
public operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) { public operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, IconChunkIdsProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) {
_builder.setIconChunkIds(index, value) _builder.setIconChunkIds(index, value)
}/** }/**
* <code>repeated bytes iconChunkIds = 9;</code> * <code>repeated bytes iconChunkIds = 10;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearIconChunkIds") @kotlin.jvm.JvmName("clearIconChunkIds")
@ -274,7 +291,7 @@ public object SnapshotKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
public class BlobsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() public class BlobsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
public val blobs: com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.Blob, BlobsProxy> public val blobs: com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.Blob, BlobsProxy>
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -283,7 +300,7 @@ public object SnapshotKt {
_builder.getBlobsMap() _builder.getBlobsMap()
) )
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
@JvmName("putBlobs") @JvmName("putBlobs")
public fun com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.Blob, BlobsProxy> public fun com.google.protobuf.kotlin.DslMap<kotlin.String, com.stevesoltys.seedvault.proto.Snapshot.Blob, BlobsProxy>
@ -291,7 +308,7 @@ public object SnapshotKt {
_builder.putBlobs(key, value) _builder.putBlobs(key, value)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("setBlobs") @JvmName("setBlobs")
@ -301,7 +318,7 @@ public object SnapshotKt {
put(key, value) put(key, value)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("removeBlobs") @JvmName("removeBlobs")
@ -310,7 +327,7 @@ public object SnapshotKt {
_builder.removeBlobs(key) _builder.removeBlobs(key)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("putAllBlobs") @JvmName("putAllBlobs")
@ -319,7 +336,7 @@ public object SnapshotKt {
_builder.putAllBlobs(map) _builder.putAllBlobs(map)
} }
/** /**
* <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 10;</code> * <code>map&lt;string, .com.stevesoltys.seedvault.proto.Snapshot.Blob&gt; blobs = 11;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@JvmName("clearBlobs") @JvmName("clearBlobs")
@ -365,24 +382,7 @@ public object SnapshotKt {
} }
/** /**
* <code>string state = 2;</code> * <code>.com.stevesoltys.seedvault.proto.Snapshot.BackupType type = 2;</code>
*/
public var state: kotlin.String
@JvmName("getState")
get() = _builder.getState()
@JvmName("setState")
set(value) {
_builder.setState(value)
}
/**
* <code>string state = 2;</code>
*/
public fun clearState() {
_builder.clearState()
}
/**
* <code>.com.stevesoltys.seedvault.proto.Snapshot.BackupType type = 3;</code>
*/ */
public var type: com.stevesoltys.seedvault.proto.Snapshot.BackupType public var type: com.stevesoltys.seedvault.proto.Snapshot.BackupType
@JvmName("getType") @JvmName("getType")
@ -392,14 +392,14 @@ public object SnapshotKt {
_builder.setType(value) _builder.setType(value)
} }
/** /**
* <code>.com.stevesoltys.seedvault.proto.Snapshot.BackupType type = 3;</code> * <code>.com.stevesoltys.seedvault.proto.Snapshot.BackupType type = 2;</code>
*/ */
public fun clearType() { public fun clearType() {
_builder.clearType() _builder.clearType()
} }
/** /**
* <code>string name = 4;</code> * <code>string name = 3;</code>
*/ */
public var name: kotlin.String public var name: kotlin.String
@JvmName("getName") @JvmName("getName")
@ -409,14 +409,14 @@ public object SnapshotKt {
_builder.setName(value) _builder.setName(value)
} }
/** /**
* <code>string name = 4;</code> * <code>string name = 3;</code>
*/ */
public fun clearName() { public fun clearName() {
_builder.clearName() _builder.clearName()
} }
/** /**
* <code>bool system = 5;</code> * <code>bool system = 4;</code>
*/ */
public var system: kotlin.Boolean public var system: kotlin.Boolean
@JvmName("getSystem") @JvmName("getSystem")
@ -426,14 +426,14 @@ public object SnapshotKt {
_builder.setSystem(value) _builder.setSystem(value)
} }
/** /**
* <code>bool system = 5;</code> * <code>bool system = 4;</code>
*/ */
public fun clearSystem() { public fun clearSystem() {
_builder.clearSystem() _builder.clearSystem()
} }
/** /**
* <code>bool launchableSystemApp = 6;</code> * <code>bool launchableSystemApp = 5;</code>
*/ */
public var launchableSystemApp: kotlin.Boolean public var launchableSystemApp: kotlin.Boolean
@JvmName("getLaunchableSystemApp") @JvmName("getLaunchableSystemApp")
@ -443,7 +443,7 @@ public object SnapshotKt {
_builder.setLaunchableSystemApp(value) _builder.setLaunchableSystemApp(value)
} }
/** /**
* <code>bool launchableSystemApp = 6;</code> * <code>bool launchableSystemApp = 5;</code>
*/ */
public fun clearLaunchableSystemApp() { public fun clearLaunchableSystemApp() {
_builder.clearLaunchableSystemApp() _builder.clearLaunchableSystemApp()
@ -456,7 +456,7 @@ public object SnapshotKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
public class ChunkIdsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() public class ChunkIdsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/** /**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
*/ */
public val chunkIds: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy> public val chunkIds: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -464,7 +464,7 @@ public object SnapshotKt {
_builder.getChunkIdsList() _builder.getChunkIdsList()
) )
/** /**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
* @param value The chunkIds to add. * @param value The chunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -472,7 +472,7 @@ public object SnapshotKt {
public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.add(value: com.google.protobuf.ByteString) { public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.add(value: com.google.protobuf.ByteString) {
_builder.addChunkIds(value) _builder.addChunkIds(value)
}/** }/**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
* @param value The chunkIds to add. * @param value The chunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -481,7 +481,7 @@ public object SnapshotKt {
public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.plusAssign(value: com.google.protobuf.ByteString) { public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.plusAssign(value: com.google.protobuf.ByteString) {
add(value) add(value)
}/** }/**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
* @param values The chunkIds to add. * @param values The chunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -489,7 +489,7 @@ public object SnapshotKt {
public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) { public fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
_builder.addAllChunkIds(values) _builder.addAllChunkIds(values)
}/** }/**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
* @param values The chunkIds to add. * @param values The chunkIds to add.
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@ -498,7 +498,7 @@ public object SnapshotKt {
public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) { public inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
addAll(values) addAll(values)
}/** }/**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
* @param index The index to set the value at. * @param index The index to set the value at.
* @param value The chunkIds to set. * @param value The chunkIds to set.
*/ */
@ -507,7 +507,7 @@ public object SnapshotKt {
public operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) { public operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, ChunkIdsProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) {
_builder.setChunkIds(index, value) _builder.setChunkIds(index, value)
}/** }/**
* <code>repeated bytes chunkIds = 7;</code> * <code>repeated bytes chunkIds = 6;</code>
*/ */
@kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearChunkIds") @kotlin.jvm.JvmName("clearChunkIds")
@ -515,7 +515,7 @@ public object SnapshotKt {
_builder.clearChunkIds() _builder.clearChunkIds()
} }
/** /**
* <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 8;</code> * <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 7;</code>
*/ */
public var apk: com.stevesoltys.seedvault.proto.Snapshot.Apk public var apk: com.stevesoltys.seedvault.proto.Snapshot.Apk
@JvmName("getApk") @JvmName("getApk")
@ -525,13 +525,13 @@ public object SnapshotKt {
_builder.setApk(value) _builder.setApk(value)
} }
/** /**
* <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 8;</code> * <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 7;</code>
*/ */
public fun clearApk() { public fun clearApk() {
_builder.clearApk() _builder.clearApk()
} }
/** /**
* <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 8;</code> * <code>.com.stevesoltys.seedvault.proto.Snapshot.Apk apk = 7;</code>
* @return Whether the apk field is set. * @return Whether the apk field is set.
*/ */
public fun hasApk(): kotlin.Boolean { public fun hasApk(): kotlin.Boolean {

View file

@ -39,7 +39,7 @@ data class BackupMetadata(
time = s.token, time = s.token,
androidVersion = s.sdkInt, androidVersion = s.sdkInt,
androidIncremental = s.androidIncremental, androidIncremental = s.androidIncremental,
deviceName = s.name, deviceName = "${s.name} - ${s.user}",
d2dBackup = s.d2D, d2dBackup = s.d2D,
packageMetadataMap = s.appsMap.mapValues { (_, app) -> packageMetadataMap = s.appsMap.mapValues { (_, app) ->
PackageMetadata.fromSnapshot(app) PackageMetadata.fromSnapshot(app)
@ -121,7 +121,6 @@ data class PackageMetadata(
companion object { companion object {
fun fromSnapshot(app: Snapshot.App) = PackageMetadata( fun fromSnapshot(app: Snapshot.App) = PackageMetadata(
time = app.time, time = app.time,
state = if (app.state.isBlank()) UNKNOWN_ERROR else PackageState.valueOf(app.state),
backupType = when (app.type) { backupType = when (app.type) {
Snapshot.BackupType.FULL -> BackupType.FULL Snapshot.BackupType.FULL -> BackupType.FULL
Snapshot.BackupType.KV -> BackupType.KV Snapshot.BackupType.KV -> BackupType.KV

View file

@ -13,8 +13,6 @@ import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import com.stevesoltys.seedvault.Clock import com.stevesoltys.seedvault.Clock
import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA
import com.stevesoltys.seedvault.transport.backup.PackageService
import com.stevesoltys.seedvault.transport.backup.isSystemApp
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import java.io.OutputStream import java.io.OutputStream
@ -31,7 +29,6 @@ internal class MetadataManager(
private val clock: Clock, private val clock: Clock,
private val metadataWriter: MetadataWriter, private val metadataWriter: MetadataWriter,
private val metadataReader: MetadataReader, private val metadataReader: MetadataReader,
private val packageService: PackageService,
) { ) {
private val uninitializedMetadata = BackupMetadata(token = -42L, salt = "foo bar") private val uninitializedMetadata = BackupMetadata(token = -42L, salt = "foo bar")
@ -52,10 +49,6 @@ internal class MetadataManager(
return field return field
} }
private val launchableSystemApps by lazy {
packageService.launchableSystemApps.map { it.activityInfo.packageName }.toSet()
}
/** /**
* Call this after a package has been backed up successfully. * Call this after a package has been backed up successfully.
* *
@ -75,15 +68,11 @@ internal class MetadataManager(
modifyCachedMetadata { modifyCachedMetadata {
val now = clock.time() val now = clock.time()
metadata.packageMetadataMap.getOrPut(packageName) { metadata.packageMetadataMap.getOrPut(packageName) {
val isSystemApp = packageInfo.isSystemApp()
PackageMetadata( PackageMetadata(
time = now, time = now,
state = APK_AND_DATA, state = APK_AND_DATA,
backupType = type, backupType = type,
size = size, size = size,
system = isSystemApp,
isLaunchableSystemApp = isSystemApp &&
launchableSystemApps.contains(packageName),
) )
}.apply { }.apply {
time = now time = now
@ -111,15 +100,11 @@ internal class MetadataManager(
check(packageState != APK_AND_DATA) { "Backup Error with non-error package state." } check(packageState != APK_AND_DATA) { "Backup Error with non-error package state." }
modifyCachedMetadata { modifyCachedMetadata {
metadata.packageMetadataMap.getOrPut(packageInfo.packageName) { metadata.packageMetadataMap.getOrPut(packageInfo.packageName) {
val isSystemApp = packageInfo.isSystemApp()
PackageMetadata( PackageMetadata(
time = 0L, time = 0L,
state = packageState, state = packageState,
backupType = backupType, backupType = backupType,
name = packageInfo.applicationInfo?.loadLabel(context.packageManager), name = packageInfo.applicationInfo?.loadLabel(context.packageManager),
system = isSystemApp,
isLaunchableSystemApp = isSystemApp &&
launchableSystemApps.contains(packageInfo.packageName),
) )
}.state = packageState }.state = packageState
} }
@ -137,14 +122,10 @@ internal class MetadataManager(
packageState: PackageState, packageState: PackageState,
) = modifyCachedMetadata { ) = modifyCachedMetadata {
metadata.packageMetadataMap.getOrPut(packageInfo.packageName) { metadata.packageMetadataMap.getOrPut(packageInfo.packageName) {
val isSystemApp = packageInfo.isSystemApp()
PackageMetadata( PackageMetadata(
time = 0L, time = 0L,
state = packageState, state = packageState,
name = packageInfo.applicationInfo?.loadLabel(context.packageManager), name = packageInfo.applicationInfo?.loadLabel(context.packageManager),
system = isSystemApp,
isLaunchableSystemApp = isSystemApp &&
launchableSystemApps.contains(packageInfo.packageName),
) )
}.apply { }.apply {
state = packageState state = packageState

View file

@ -9,7 +9,7 @@ import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module import org.koin.dsl.module
val metadataModule = module { val metadataModule = module {
single { MetadataManager(androidContext(), get(), get(), get(), get()) } single { MetadataManager(androidContext(), get(), get(), get()) }
single<MetadataWriter> { MetadataWriterImpl() } single<MetadataWriter> { MetadataWriterImpl() }
single<MetadataReader> { MetadataReaderImpl(get()) } single<MetadataReader> { MetadataReaderImpl(get()) }
} }

View file

@ -5,6 +5,7 @@
package com.stevesoltys.seedvault.transport.backup package com.stevesoltys.seedvault.transport.backup
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
@ -18,7 +19,6 @@ import com.stevesoltys.seedvault.Clock
import com.stevesoltys.seedvault.header.VERSION import com.stevesoltys.seedvault.header.VERSION
import com.stevesoltys.seedvault.metadata.BackupType import com.stevesoltys.seedvault.metadata.BackupType
import com.stevesoltys.seedvault.metadata.MetadataManager import com.stevesoltys.seedvault.metadata.MetadataManager
import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA
import com.stevesoltys.seedvault.proto.Snapshot import com.stevesoltys.seedvault.proto.Snapshot
import com.stevesoltys.seedvault.proto.Snapshot.Apk import com.stevesoltys.seedvault.proto.Snapshot.Apk
import com.stevesoltys.seedvault.proto.Snapshot.App import com.stevesoltys.seedvault.proto.Snapshot.App
@ -28,6 +28,9 @@ import io.github.oshai.kotlinlogging.KotlinLogging
import org.calyxos.seedvault.core.backends.AppBackupFileType import org.calyxos.seedvault.core.backends.AppBackupFileType
import org.calyxos.seedvault.core.toHexString import org.calyxos.seedvault.core.toHexString
/**
* Creates a new [SnapshotCreator], because one is only valid for a single backup run.
*/
internal class SnapshotCreatorFactory( internal class SnapshotCreatorFactory(
private val context: Context, private val context: Context,
private val clock: Clock, private val clock: Clock,
@ -39,6 +42,10 @@ internal class SnapshotCreatorFactory(
SnapshotCreator(context, clock, packageService, settingsManager, metadataManager) SnapshotCreator(context, clock, packageService, settingsManager, metadataManager)
} }
/**
* Assembles snapshot information over the course of a single backup run
* and creates a [Snapshot] object in the end by calling [finalizeSnapshot].
*/
internal class SnapshotCreator( internal class SnapshotCreator(
private val context: Context, private val context: Context,
private val clock: Clock, private val clock: Clock,
@ -48,14 +55,21 @@ internal class SnapshotCreator(
) { ) {
private val log = KotlinLogging.logger { } private val log = KotlinLogging.logger { }
private val snapshotBuilder = Snapshot.newBuilder() private val snapshotBuilder = Snapshot.newBuilder()
private val appBuilderMap = mutableMapOf<String, App.Builder>() private val appBuilderMap = mutableMapOf<String, App.Builder>()
private val blobsMap = mutableMapOf<String, Blob>() private val blobsMap = mutableMapOf<String, Blob>()
private val launchableSystemApps by lazy { private val launchableSystemApps by lazy {
// as we can't ask [PackageInfo] for this, we keep a set of packages around
packageService.launchableSystemApps.map { it.activityInfo.packageName }.toSet() packageService.launchableSystemApps.map { it.activityInfo.packageName }.toSet()
} }
/**
* Call this after all blobs for the given [apk] have been saved to the backend.
* The [apk] must contain the ordered list of chunk IDs
* and the given [blobMap] must have one [Blob] per chunk ID.
*/
fun onApkBackedUp( fun onApkBackedUp(
packageInfo: PackageInfo, packageInfo: PackageInfo,
apk: Apk, apk: Apk,
@ -71,6 +85,14 @@ internal class SnapshotCreator(
blobsMap.putAll(blobMap) blobsMap.putAll(blobMap)
} }
/**
* Call this after all blobs for the package identified by the given [packageInfo]
* have been saved to the backend.
* The given [backupData] must contain the full ordered list of [BackupData.chunkIds]
* and the [BackupData.blobMap] must have one [Blob] per chunk ID.
*
* Failure to call this method results in the package effectively not getting backed up.
*/
fun onPackageBackedUp( fun onPackageBackedUp(
packageInfo: PackageInfo, packageInfo: PackageInfo,
backupType: BackupType, backupType: BackupType,
@ -83,7 +105,6 @@ internal class SnapshotCreator(
App.newBuilder() App.newBuilder()
}.apply { }.apply {
time = clock.time() time = clock.time()
state = APK_AND_DATA.name // TODO review those states and their usefulness for snapshot
type = backupType.forSnapshot() type = backupType.forSnapshot()
val label = packageInfo.applicationInfo?.loadLabel(context.packageManager) val label = packageInfo.applicationInfo?.loadLabel(context.packageManager)
if (label != null) name = label.toString() if (label != null) name = label.toString()
@ -95,26 +116,31 @@ internal class SnapshotCreator(
metadataManager.onPackageBackedUp(packageInfo, backupType, backupData.size) metadataManager.onPackageBackedUp(packageInfo, backupType, backupData.size)
} }
/**
* Call this after all blobs for the app icons have been saved to the backend.
*/
fun onIconsBackedUp(backupData: BackupData) { fun onIconsBackedUp(backupData: BackupData) {
snapshotBuilder.addAllIconChunkIds(backupData.chunkIds.forProto()) snapshotBuilder.addAllIconChunkIds(backupData.chunkIds.forProto())
blobsMap.putAll(backupData.blobMap) blobsMap.putAll(backupData.blobMap)
} }
/**
* Must get called after all backup data was saved to the backend.
* Returns the assembled [Snapshot] which must be saved to the backend as well
* to complete the current backup run.
*
* Internal state will be cleared to free up memory.
* Still, it isn't safe to re-use an instance of this class, after it has been finalized.
*/
fun finalizeSnapshot(): Snapshot { fun finalizeSnapshot(): Snapshot {
log.info { "finalizeSnapshot()" } log.info { "finalizeSnapshot()" }
val userName = getUserName()
val deviceName = if (userName == null) {
"${Build.MANUFACTURER} ${Build.MODEL}"
} else {
"${Build.MANUFACTURER} ${Build.MODEL} - $userName"
}
@SuppressLint("HardwareIds") @SuppressLint("HardwareIds")
val snapshot = snapshotBuilder.apply { val snapshot = snapshotBuilder.apply {
version = VERSION.toInt() version = VERSION.toInt()
token = clock.time() token = clock.time()
name = deviceName name = "${Build.MANUFACTURER} ${Build.MODEL}"
androidId = Settings.Secure.getString(context.contentResolver, ANDROID_ID) user = getUserName() ?: ""
androidId = Settings.Secure.getString(context.contentResolver, ANDROID_ID) ?: ""
sdkInt = Build.VERSION.SDK_INT sdkInt = Build.VERSION.SDK_INT
androidIncremental = Build.VERSION.INCREMENTAL androidIncremental = Build.VERSION.INCREMENTAL
d2D = settingsManager.d2dBackupsEnabled() d2D = settingsManager.d2dBackupsEnabled()
@ -123,11 +149,13 @@ internal class SnapshotCreator(
}.build() }.build()
appBuilderMap.clear() appBuilderMap.clear()
snapshotBuilder.clear() snapshotBuilder.clear()
blobsMap.clear()
return snapshot return snapshot
} }
private fun getUserName(): String? { private fun getUserName(): String? {
val perm = "android.permission.QUERY_USERS" @Suppress("UNRESOLVED_REFERENCE") // hidden AOSP API
val perm = Manifest.permission.QUERY_USERS
return if (context.checkSelfPermission(perm) == PERMISSION_GRANTED) { return if (context.checkSelfPermission(perm) == PERMISSION_GRANTED) {
val userManager = context.getSystemService(UserManager::class.java) ?: return null val userManager = context.getSystemService(UserManager::class.java) ?: return null
userManager.userName userManager.userName

View file

@ -8,23 +8,23 @@ message Snapshot {
uint32 version = 1; uint32 version = 1;
uint64 token = 2; uint64 token = 2;
string name = 3; string name = 3;
string androidId = 4; string user = 4;
uint32 sdkInt = 5; string androidId = 5;
string androidIncremental = 6; uint32 sdkInt = 6;
bool d2d = 7; string androidIncremental = 7;
map<string, App> apps = 8; bool d2d = 8;
repeated bytes iconChunkIds = 9; map<string, App> apps = 9;
map<string, Blob> blobs = 10; repeated bytes iconChunkIds = 10;
map<string, Blob> blobs = 11;
message App { message App {
uint64 time = 1; uint64 time = 1;
string state = 2; BackupType type = 2;
BackupType type = 3; string name = 3;
string name = 4; bool system = 4;
bool system = 5; bool launchableSystemApp = 5;
bool launchableSystemApp = 6; repeated bytes chunkIds = 6;
repeated bytes chunkIds = 7; Apk apk = 7;
Apk apk = 8;
} }
enum BackupType { enum BackupType {

View file

@ -9,7 +9,6 @@ import android.content.Context
import android.content.Context.MODE_PRIVATE import android.content.Context.MODE_PRIVATE
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.ApplicationInfo.FLAG_ALLOW_BACKUP import android.content.pm.ApplicationInfo.FLAG_ALLOW_BACKUP
import android.content.pm.ApplicationInfo.FLAG_SYSTEM
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
@ -23,7 +22,6 @@ import com.stevesoltys.seedvault.metadata.PackageState.NOT_ALLOWED
import com.stevesoltys.seedvault.metadata.PackageState.NO_DATA import com.stevesoltys.seedvault.metadata.PackageState.NO_DATA
import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED
import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.transport.backup.PackageService
import io.mockk.Runs import io.mockk.Runs
import io.mockk.every import io.mockk.every
import io.mockk.just import io.mockk.just
@ -37,7 +35,6 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.koin.core.context.stopKoin import org.koin.core.context.stopKoin
import org.robolectric.annotation.Config import org.robolectric.annotation.Config
import java.io.ByteArrayOutputStream
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import kotlin.random.Random import kotlin.random.Random
@ -53,7 +50,6 @@ class MetadataManagerTest {
private val clock: Clock = mockk() private val clock: Clock = mockk()
private val metadataWriter: MetadataWriter = mockk() private val metadataWriter: MetadataWriter = mockk()
private val metadataReader: MetadataReader = mockk() private val metadataReader: MetadataReader = mockk()
private val packageService: PackageService = mockk()
private val settingsManager: SettingsManager = mockk() private val settingsManager: SettingsManager = mockk()
private val manager = MetadataManager( private val manager = MetadataManager(
@ -61,7 +57,6 @@ class MetadataManagerTest {
clock = clock, clock = clock,
metadataWriter = metadataWriter, metadataWriter = metadataWriter,
metadataReader = metadataReader, metadataReader = metadataReader,
packageService = packageService,
) )
private val packageManager: PackageManager = mockk() private val packageManager: PackageManager = mockk()
@ -76,7 +71,6 @@ class MetadataManagerTest {
private val saltBytes = Random.nextBytes(METADATA_SALT_SIZE) private val saltBytes = Random.nextBytes(METADATA_SALT_SIZE)
private val salt = saltBytes.encodeBase64() private val salt = saltBytes.encodeBase64()
private val initialMetadata = BackupMetadata(token = token, salt = salt) private val initialMetadata = BackupMetadata(token = token, salt = salt)
private val storageOutputStream = ByteArrayOutputStream()
private val cacheOutputStream: FileOutputStream = mockk() private val cacheOutputStream: FileOutputStream = mockk()
private val cacheInputStream: FileInputStream = mockk() private val cacheInputStream: FileInputStream = mockk()
private val encodedMetadata = getRandomByteArray() private val encodedMetadata = getRandomByteArray()
@ -93,7 +87,6 @@ class MetadataManagerTest {
@Test @Test
fun `test onPackageBackedUp()`() { fun `test onPackageBackedUp()`() {
packageInfo.applicationInfo!!.flags = FLAG_SYSTEM
val updatedMetadata = initialMetadata.copy( val updatedMetadata = initialMetadata.copy(
time = time, time = time,
packageMetadataMap = PackageMetadataMap() // otherwise this isn't copied, but referenced packageMetadataMap = PackageMetadataMap() // otherwise this isn't copied, but referenced
@ -103,7 +96,6 @@ class MetadataManagerTest {
updatedMetadata.packageMetadataMap[packageName] = packageMetadata updatedMetadata.packageMetadataMap[packageName] = packageMetadata
every { context.packageManager } returns packageManager every { context.packageManager } returns packageManager
every { packageService.launchableSystemApps } returns emptyList()
expectReadFromCache() expectReadFromCache()
every { clock.time() } returns time every { clock.time() } returns time
expectWriteToCache(initialMetadata) expectWriteToCache(initialMetadata)
@ -115,8 +107,6 @@ class MetadataManagerTest {
state = APK_AND_DATA, state = APK_AND_DATA,
backupType = BackupType.FULL, backupType = BackupType.FULL,
size = size, size = size,
system = true,
isLaunchableSystemApp = false,
), ),
manager.getPackageMetadata(packageName) manager.getPackageMetadata(packageName)
) )

View file

@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: 2024 The Calyx Institute
* SPDX-License-Identifier: Apache-2.0
*/
package com.stevesoltys.seedvault.transport.backup
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.ApplicationInfo.FLAG_SYSTEM
import android.content.pm.ResolveInfo
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.stevesoltys.seedvault.TestApp
import com.stevesoltys.seedvault.header.VERSION
import com.stevesoltys.seedvault.metadata.BackupType
import com.stevesoltys.seedvault.proto.Snapshot
import com.stevesoltys.seedvault.transport.TransportTest
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import kotlin.random.Random
@RunWith(AndroidJUnit4::class)
@Config(
sdk = [34], // TODO: Drop once robolectric supports 35
application = TestApp::class
)
internal class SnapshotCreatorTest : TransportTest() {
private val ctx: Context = ApplicationProvider.getApplicationContext()
private val packageService: PackageService = mockk()
private val snapshotCreator =
SnapshotCreator(ctx, clock, packageService, settingsManager, metadataManager)
@Test
fun `test onApkBackedUp`() {
every { applicationInfo.loadLabel(any()) } returns name
every { clock.time() } returns token
every { settingsManager.d2dBackupsEnabled() } returns Random.nextBoolean()
snapshotCreator.onApkBackedUp(packageInfo, apk, blobMap)
val s = snapshotCreator.finalizeSnapshot()
assertEquals(apk, s.appsMap[packageName]?.apk)
assertEquals(name, s.appsMap[packageName]?.name)
assertEquals(blobMap, s.blobsMap)
}
@Test
fun `test onPackageBackedUp`() {
val size = apkBackupData.size
val isSystem = Random.nextBoolean()
val appInfo = mockk<ApplicationInfo> {
flags = if (isSystem) FLAG_SYSTEM else 0
}
packageInfo.applicationInfo = appInfo
val resolveInfo = ResolveInfo().apply { // if isSystem, then it will be launchable
activityInfo = ActivityInfo().apply {
packageName = this@SnapshotCreatorTest.packageName
}
}
every { appInfo.loadLabel(any()) } returns name
every { metadataManager.onPackageBackedUp(packageInfo, BackupType.FULL, size) } just Runs
every { clock.time() } returns token andThen token + 1
every { settingsManager.d2dBackupsEnabled() } returns Random.nextBoolean()
every { packageService.launchableSystemApps } returns listOf(resolveInfo)
snapshotCreator.onPackageBackedUp(packageInfo, BackupType.FULL, apkBackupData)
val s = snapshotCreator.finalizeSnapshot()
assertEquals(name, s.appsMap[packageName]?.name)
assertEquals(token, s.appsMap[packageName]?.time)
assertEquals(Snapshot.BackupType.FULL, s.appsMap[packageName]?.type)
assertEquals(isSystem, s.appsMap[packageName]?.system)
assertEquals(isSystem, s.appsMap[packageName]?.launchableSystemApp)
assertEquals(apkBackupData.chunkIds.forProto(), s.appsMap[packageName]?.chunkIdsList)
assertEquals(apkBackupData.blobMap, s.blobsMap)
}
@Test
fun `test onPackageBackedUp handles no application info`() {
packageInfo.applicationInfo = null
val size = apkBackupData.size
every { metadataManager.onPackageBackedUp(packageInfo, BackupType.FULL, size) } just Runs
every { clock.time() } returns token andThen token + 1
every { settingsManager.d2dBackupsEnabled() } returns Random.nextBoolean()
every { packageService.launchableSystemApps } returns emptyList()
snapshotCreator.onPackageBackedUp(packageInfo, BackupType.FULL, apkBackupData)
snapshotCreator.finalizeSnapshot()
}
@Test
fun `test onIconsBackedUp`() {
every { clock.time() } returns token andThen token + 1
every { settingsManager.d2dBackupsEnabled() } returns Random.nextBoolean()
snapshotCreator.onIconsBackedUp(apkBackupData)
val s = snapshotCreator.finalizeSnapshot()
assertEquals(apkBackupData.chunkIds.forProto(), s.iconChunkIdsList)
assertEquals(apkBackupData.blobMap, s.blobsMap)
}
@Test
fun `test finalize`() {
val d2d = Random.nextBoolean()
every { clock.time() } returns token
every { settingsManager.d2dBackupsEnabled() } returns d2d
val s = snapshotCreator.finalizeSnapshot()
assertEquals(VERSION, s.version.toByte())
assertEquals(token, s.token)
assertEquals("robolectric robolectric", s.name)
assertEquals("", s.user) // no perm
assertEquals("", s.androidId) // not mocked
assertEquals(34, s.sdkInt) // as per config above, needs bump once possible
assertEquals("unknown", s.androidIncremental)
assertEquals(d2d, s.d2D)
assertEquals(0, s.appsCount)
assertEquals(0, s.iconChunkIdsCount)
assertEquals(emptyMap<String, Snapshot.Blob>(), s.blobsMap)
}
}