@@ -25,6 +25,7 @@ import com.stevesoltys.seedvault.proto.Snapshot
25
25
import com.stevesoltys.seedvault.proto.Snapshot.Apk
26
26
import com.stevesoltys.seedvault.proto.Snapshot.App
27
27
import com.stevesoltys.seedvault.proto.Snapshot.Blob
28
+ import com.stevesoltys.seedvault.transport.backup.BackupInitializer
28
29
import com.stevesoltys.seedvault.transport.backup.PackageService
29
30
import com.stevesoltys.seedvault.transport.backup.isSystemApp
30
31
import io.github.oshai.kotlinlogging.KotlinLogging
@@ -41,6 +42,7 @@ internal class SnapshotCreator(
41
42
private val clock : Clock ,
42
43
private val packageService : PackageService ,
43
44
private val metadataManager : MetadataManager ,
45
+ private val backupInitializer : BackupInitializer ,
44
46
) {
45
47
46
48
private val log = KotlinLogging .logger { }
@@ -115,44 +117,55 @@ internal class SnapshotCreator(
115
117
* we try to extract data from the given [snapshot] (ideally we latest we have) and
116
118
* add it to the current snapshot under construction.
117
119
*
118
- * @param warnNoData log a warning, if [snapshot] had no data for the given [packageName] .
120
+ * @param isStopped set to true if the app had no data, because it is currently force-stopped .
119
121
*/
120
- fun onNoDataInCurrentRun (snapshot : Snapshot , packageName : String , isStopped : Boolean = false) {
121
- log.info { " onKvPackageNotChanged(${snapshot.token} , $packageName )" }
122
+ fun onNoDataInCurrentRun (snapshot : Snapshot ? , packageName : String , isStopped : Boolean = false) {
123
+ log.info { " onKvPackageNotChanged(${snapshot? .token} , $packageName )" }
122
124
123
125
if (appBuilderMap.containsKey(packageName)) {
124
126
// the system backs up K/V apps repeatedly, e.g. @pm@
125
127
log.info { " Already have data for $packageName in current snapshot, not touching it" }
126
128
return
127
129
}
128
- val app = snapshot.appsMap[packageName]
129
- if (app == null ) {
130
- if (! isStopped) log.error {
131
- " No changed data for $packageName , but we had no data for it"
130
+ if (snapshot == null ) {
131
+ log.error { " No latest snapshot! Initializing transport..." }
132
+ // Tell the system that it needs to initialize our transport,
133
+ // so it stops telling us that it has no data.
134
+ // It seems crazy that we can do this mid-backup
135
+ val error = { log.error { " Error initializing transport." } }
136
+ backupInitializer.initialize(error) {
137
+ log.info { " Success initializing transport." }
138
+ }
139
+ } else {
140
+ val app = snapshot.appsMap[packageName]
141
+ if (app == null ) {
142
+ if (! isStopped) log.error {
143
+ " No changed data for $packageName , but we had no data for it"
144
+ }
145
+ return
132
146
}
133
- return
134
- }
135
147
136
- // get chunkIds from last snapshot
137
- val chunkIds = app.chunkIdsList.hexFromProto() +
138
- app.apk.splitsList.flatMap { it.chunkIdsList }.hexFromProto()
148
+ // get chunkIds from last snapshot
149
+ val chunkIds = app.chunkIdsList.hexFromProto() +
150
+ app.apk.splitsList.flatMap { it.chunkIdsList }.hexFromProto()
139
151
140
- // get blobs for chunkIds
141
- val blobMap = mutableMapOf<String , Blob >()
142
- chunkIds.forEach { chunkId ->
143
- val blob = snapshot.blobsMap[chunkId]
144
- if (blob == null ) log.error { " No blob for $packageName chunk $chunkId " }
145
- else blobMap[chunkId] = blob
146
- }
152
+ // get blobs for chunkIds
153
+ val blobMap = mutableMapOf<String , Blob >()
154
+ chunkIds.forEach { chunkId ->
155
+ val blob = snapshot.blobsMap[chunkId]
156
+ if (blob == null ) log.error { " No blob for $packageName chunk $chunkId " }
157
+ else blobMap[chunkId] = blob
158
+ }
147
159
148
- // add info to current snapshot
149
- appBuilderMap[packageName] = app.toBuilder()
150
- blobsMap.putAll(blobMap)
160
+ // add info to current snapshot
161
+ appBuilderMap[packageName] = app.toBuilder()
162
+ blobsMap.putAll(blobMap)
151
163
152
- // record local metadata if this is not a stopped app
153
- if (! isStopped) {
154
- val packageInfo = PackageInfo ().apply { this .packageName = packageName }
155
- metadataManager.onPackageBackedUp(packageInfo, app.type.toBackupType(), app.size)
164
+ // record local metadata if this is not a stopped app
165
+ if (! isStopped) {
166
+ val packageInfo = PackageInfo ().apply { this .packageName = packageName }
167
+ metadataManager.onPackageBackedUp(packageInfo, app.type.toBackupType(), app.size)
168
+ }
156
169
}
157
170
}
158
171
0 commit comments