@@ -79,7 +79,9 @@ public protocol BackupListMediaManager {
7979
8080 func getLastFailingIntegrityCheckResult( tx: DBReadTransaction ) throws -> ListMediaIntegrityCheckResult ?
8181
82- func performUploadIntegrityCheck( ) async throws -> ListMediaIntegrityCheckResult
82+ func getMostRecentIntegrityCheckResult( tx: DBReadTransaction ) throws -> ListMediaIntegrityCheckResult ?
83+
84+ func setManualNeedsListMedia( tx: DBWriteTransaction )
8385}
8486
8587public class BackupListMediaManagerImpl : BackupListMediaManager {
@@ -151,8 +153,17 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
151153 try kvStore. getCodableValue ( forKey: Constants . lastNonEmptyIntegrityCheckResultKey, transaction: tx)
152154 }
153155
156+ public func getMostRecentIntegrityCheckResult( tx: DBReadTransaction ) throws -> ListMediaIntegrityCheckResult ? {
157+ try kvStore. getCodableValue ( forKey: Constants . lastIntegrityCheckResultKey, transaction: tx)
158+ }
159+
154160 private let taskQueue = ConcurrentTaskQueue ( concurrentLimit: 1 )
155161
162+ /// Nil if we have not run list media this app launch (only held in memory).
163+ /// Set to the upload era where we ran list media this app launch.
164+ /// Should only be accessed from the taskQueue for locking purposes.
165+ private var lastListMediaUploadEraThisAppSession : String ?
166+
156167 public func queryListMediaIfNeeded( ) async throws {
157168 let task = Task {
158169 // Enqueue in a concurrent(1) task queue; we only want to run one of these at a time.
@@ -175,13 +186,7 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
175186 )
176187 }
177188
178- public func performUploadIntegrityCheck( ) async throws -> ListMediaIntegrityCheckResult {
179- return try await taskQueue. run {
180- try await self . _queryListMediaIfNeeded ( forceIfNotNeeded: true )
181- }
182- }
183-
184- private func _queryListMediaIfNeeded( forceIfNotNeeded: Bool = false ) async throws -> ListMediaIntegrityCheckResult {
189+ private func _queryListMediaIfNeeded( ) async throws -> ListMediaIntegrityCheckResult {
185190 guard FeatureFlags . Backups. supported else {
186191 return . empty( listMediaStartTimestamp: 0 )
187192 }
@@ -216,7 +221,7 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
216221 integrityCheckResult
217222 )
218223 }
219- guard needsToQuery || forceIfNotNeeded else {
224+ guard needsToQuery else {
220225 return . empty( listMediaStartTimestamp: 0 )
221226 }
222227
@@ -1115,6 +1120,16 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
11151120 case . free:
11161121 return false
11171122 case . paid, . paidExpiringSoon, . paidAsTester:
1123+ // Only query once per app session per upload era; this overrides the manual
1124+ // toggle and the date-based checks.
1125+ if lastListMediaUploadEraThisAppSession == currentUploadEra {
1126+ return false
1127+ }
1128+
1129+ if kvStore. getBool ( Constants . manuallySetNeedsListMediaKey, defaultValue: false , transaction: tx) {
1130+ return true
1131+ }
1132+
11181133 // If paid tier, query periodically as a catch-all to ensure local state
11191134 // stays in sync with the server.
11201135 let nowMs = dateProvider ( ) . ows_millisecondsSince1970
@@ -1157,16 +1172,19 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
11571172 self . kvStore. setBool ( true , key: Constants . hasEverRunListMediaKey, transaction: tx)
11581173 if let uploadEra = kvStore. getString ( Constants . inProgressUploadEraKey, transaction: tx) {
11591174 self . kvStore. setString ( uploadEra, key: Constants . lastListMediaUploadEraKey, transaction: tx)
1175+ self . lastListMediaUploadEraThisAppSession = uploadEra
11601176 self . kvStore. removeValue ( forKey: Constants . inProgressUploadEraKey, transaction: tx)
11611177 } else {
11621178 owsFailDebug ( " Missing in progress upload era? " )
11631179 }
11641180 self . kvStore. setUInt64 ( startTimestamp, key: Constants . lastListMediaStartTimestampKey, transaction: tx)
1181+ self . kvStore. setBool ( false , key: Constants . manuallySetNeedsListMediaKey, transaction: tx)
11651182 kvStore. removeValue ( forKey: Constants . inProgressListMediaStartTimestampKey, transaction: tx)
11661183
11671184 if integrityCheckResult. hasFailures {
11681185 try kvStore. setCodable ( integrityCheckResult, key: Constants . lastNonEmptyIntegrityCheckResultKey, transaction: tx)
11691186 }
1187+ try kvStore. setCodable ( integrityCheckResult, key: Constants . lastIntegrityCheckResultKey, transaction: tx)
11701188 kvStore. removeValue ( forKey: Constants . inProgressIntegrityCheckResultKey, transaction: tx)
11711189
11721190 self . kvStore. setBool ( false , key: Constants . hasCompletedListingMediaKey, transaction: tx)
@@ -1184,10 +1202,15 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
11841202 // Rotate the last integrity check failure when disabled
11851203 db. write { tx in
11861204 kvStore. removeValue ( forKey: Constants . lastNonEmptyIntegrityCheckResultKey, transaction: tx)
1205+ kvStore. removeValue ( forKey: Constants . lastIntegrityCheckResultKey, transaction: tx)
11871206 }
11881207 }
11891208 }
11901209
1210+ public func setManualNeedsListMedia( tx: DBWriteTransaction ) {
1211+ kvStore. setBool ( true , key: Constants . manuallySetNeedsListMediaKey, transaction: tx)
1212+ }
1213+
11911214 private enum Constants {
11921215 /// Maps to the upload era (active subscription) when we last queried the list media
11931216 /// endpoint, or nil if its never been queried.
@@ -1197,6 +1220,8 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
11971220 static let lastListMediaStartTimestampKey = " lastListMediaTimestamp "
11981221 static let inProgressListMediaStartTimestampKey = " inProgressListMediaTimestamp "
11991222
1223+ static let manuallySetNeedsListMediaKey = " manuallySetNeedsListMediaKey "
1224+
12001225 /// True if we've ever run list media in the lifetime of this app.
12011226 static let hasEverRunListMediaKey = " hasEverRunListMedia "
12021227
@@ -1221,6 +1246,7 @@ public class BackupListMediaManagerImpl: BackupListMediaManager {
12211246 static let hasCompletedEnumeratingAttachmentsKey = " hasCompletedEnumeratingAttachmentsKey "
12221247
12231248 static let lastNonEmptyIntegrityCheckResultKey = " lastNonEmptyIntegrityCheckResultKey "
1249+ static let lastIntegrityCheckResultKey = " lastIntegrityCheckResultKey "
12241250 static let inProgressIntegrityCheckResultKey = " inProgressIntegrityCheckResultKey "
12251251 }
12261252}
@@ -1238,8 +1264,12 @@ class MockBackupListMediaManager: BackupListMediaManager {
12381264 nil
12391265 }
12401266
1241- func performUploadIntegrityCheck( ) async throws -> ListMediaIntegrityCheckResult {
1242- return . empty( listMediaStartTimestamp: 0 )
1267+ func getMostRecentIntegrityCheckResult( tx: DBReadTransaction ) throws -> ListMediaIntegrityCheckResult ? {
1268+ nil
1269+ }
1270+
1271+ func setManualNeedsListMedia( tx: DBWriteTransaction ) {
1272+ // Nothing
12431273 }
12441274}
12451275
0 commit comments