124 lines
3.5 KiB
Swift
124 lines
3.5 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public protocol OWSDeviceManager {
|
|
|
|
func warmCaches()
|
|
|
|
// MARK: Has received sync message
|
|
|
|
func setHasReceivedSyncMessage(
|
|
lastReceivedAt: Date,
|
|
transaction: DBWriteTransaction
|
|
)
|
|
|
|
func hasReceivedSyncMessage(inLastSeconds seconds: UInt) -> Bool
|
|
|
|
// MARK: May have linked devices
|
|
|
|
func setMayHaveLinkedDevices(
|
|
_ mayHaveLinkedDevices: Bool,
|
|
transaction: DBWriteTransaction
|
|
)
|
|
|
|
func mayHaveLinkedDevices(transaction: DBReadTransaction) -> Bool
|
|
}
|
|
|
|
extension OWSDeviceManager {
|
|
func setHasReceivedSyncMessage(transaction: DBWriteTransaction) {
|
|
setHasReceivedSyncMessage(lastReceivedAt: Date(), transaction: transaction)
|
|
}
|
|
}
|
|
|
|
class OWSDeviceManagerImpl: OWSDeviceManager {
|
|
private enum Constants {
|
|
static let keyValueStoreCollectionName = "kTSStorageManager_OWSDeviceCollection"
|
|
static let mayHaveLinkedDevicesKey = "kTSStorageManager_MayHaveLinkedDevices"
|
|
static let lastReceivedSyncMessageKey = "kLastReceivedSyncMessage"
|
|
}
|
|
|
|
private let databaseStorage: DB
|
|
private let keyValueStore: KeyValueStore
|
|
|
|
private var lastReceivedSyncMessageAt: AtomicOptional<Date> = .init(nil, lock: .init())
|
|
|
|
init(
|
|
databaseStorage: DB,
|
|
keyValueStoreFactory: KeyValueStoreFactory
|
|
) {
|
|
self.databaseStorage = databaseStorage
|
|
|
|
keyValueStore = keyValueStoreFactory.keyValueStore(
|
|
collection: Constants.keyValueStoreCollectionName
|
|
)
|
|
}
|
|
|
|
func warmCaches() {
|
|
databaseStorage.read { transaction in
|
|
if let lastReceived = keyValueStore.getDate(
|
|
Constants.lastReceivedSyncMessageKey,
|
|
transaction: transaction
|
|
) {
|
|
_ = lastReceivedSyncMessageAt.tryToSetIfNil(lastReceived)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Has received sync message
|
|
|
|
func hasReceivedSyncMessage(inLastSeconds lastSeconds: UInt) -> Bool {
|
|
guard let lastReceivedSyncMessageAt = lastReceivedSyncMessageAt.get() else {
|
|
return false
|
|
}
|
|
|
|
let timeIntervalSinceLastReceived = fabs(lastReceivedSyncMessageAt.timeIntervalSinceNow)
|
|
|
|
return timeIntervalSinceLastReceived < Double(lastSeconds)
|
|
}
|
|
|
|
func setHasReceivedSyncMessage(
|
|
lastReceivedAt: Date,
|
|
transaction: DBWriteTransaction
|
|
) {
|
|
self.lastReceivedSyncMessageAt.set(lastReceivedAt)
|
|
|
|
keyValueStore.setDate(
|
|
lastReceivedAt,
|
|
key: Constants.lastReceivedSyncMessageKey,
|
|
transaction: transaction
|
|
)
|
|
|
|
setMayHaveLinkedDevices(true, transaction: transaction)
|
|
}
|
|
|
|
// MARK: May have linked devices
|
|
|
|
/// Returns whether or not we may have linked devices.
|
|
///
|
|
/// By default, returns `true`. If we confirm we have no linked devices,
|
|
/// we should set this flag to `false` via ``setMayHaveLinkedDevices`` so
|
|
/// as to avoid unnecessary sync message sending.
|
|
func mayHaveLinkedDevices(transaction: DBReadTransaction) -> Bool {
|
|
return keyValueStore.getBool(
|
|
Constants.mayHaveLinkedDevicesKey,
|
|
defaultValue: true,
|
|
transaction: transaction
|
|
)
|
|
}
|
|
|
|
func setMayHaveLinkedDevices(
|
|
_ mayHaveLinkedDevices: Bool,
|
|
transaction: DBWriteTransaction
|
|
) {
|
|
keyValueStore.setBool(
|
|
mayHaveLinkedDevices,
|
|
key: Constants.mayHaveLinkedDevicesKey,
|
|
transaction: transaction
|
|
)
|
|
}
|
|
}
|