Improve Live Location Sharing with reduced accuracy mode (#5461)
This commit is contained in:
@@ -2209,6 +2209,11 @@ class CLLocationManagerMock: CLLocationManagerProtocol, @unchecked Sendable {
|
|||||||
set(value) { underlyingDistanceFilter = value }
|
set(value) { underlyingDistanceFilter = value }
|
||||||
}
|
}
|
||||||
var underlyingDistanceFilter: CLLocationDistance!
|
var underlyingDistanceFilter: CLLocationDistance!
|
||||||
|
var pausesLocationUpdatesAutomatically: Bool {
|
||||||
|
get { return underlyingPausesLocationUpdatesAutomatically }
|
||||||
|
set(value) { underlyingPausesLocationUpdatesAutomatically = value }
|
||||||
|
}
|
||||||
|
var underlyingPausesLocationUpdatesAutomatically: Bool!
|
||||||
var authorizationStatus: CLAuthorizationStatus {
|
var authorizationStatus: CLAuthorizationStatus {
|
||||||
get { return underlyingAuthorizationStatus }
|
get { return underlyingAuthorizationStatus }
|
||||||
set(value) { underlyingAuthorizationStatus = value }
|
set(value) { underlyingAuthorizationStatus = value }
|
||||||
@@ -2325,76 +2330,6 @@ class CLLocationManagerMock: CLLocationManagerProtocol, @unchecked Sendable {
|
|||||||
stopUpdatingLocationCallsCount += 1
|
stopUpdatingLocationCallsCount += 1
|
||||||
stopUpdatingLocationClosure?()
|
stopUpdatingLocationClosure?()
|
||||||
}
|
}
|
||||||
//MARK: - startMonitoringSignificantLocationChanges
|
|
||||||
|
|
||||||
var startMonitoringSignificantLocationChangesUnderlyingCallsCount = 0
|
|
||||||
var startMonitoringSignificantLocationChangesCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return startMonitoringSignificantLocationChangesUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = startMonitoringSignificantLocationChangesUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
startMonitoringSignificantLocationChangesUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
startMonitoringSignificantLocationChangesUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var startMonitoringSignificantLocationChangesCalled: Bool {
|
|
||||||
return startMonitoringSignificantLocationChangesCallsCount > 0
|
|
||||||
}
|
|
||||||
var startMonitoringSignificantLocationChangesClosure: (() -> Void)?
|
|
||||||
|
|
||||||
func startMonitoringSignificantLocationChanges() {
|
|
||||||
startMonitoringSignificantLocationChangesCallsCount += 1
|
|
||||||
startMonitoringSignificantLocationChangesClosure?()
|
|
||||||
}
|
|
||||||
//MARK: - stopMonitoringSignificantLocationChanges
|
|
||||||
|
|
||||||
var stopMonitoringSignificantLocationChangesUnderlyingCallsCount = 0
|
|
||||||
var stopMonitoringSignificantLocationChangesCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return stopMonitoringSignificantLocationChangesUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = stopMonitoringSignificantLocationChangesUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
stopMonitoringSignificantLocationChangesUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
stopMonitoringSignificantLocationChangesUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var stopMonitoringSignificantLocationChangesCalled: Bool {
|
|
||||||
return stopMonitoringSignificantLocationChangesCallsCount > 0
|
|
||||||
}
|
|
||||||
var stopMonitoringSignificantLocationChangesClosure: (() -> Void)?
|
|
||||||
|
|
||||||
func stopMonitoringSignificantLocationChanges() {
|
|
||||||
stopMonitoringSignificantLocationChangesCallsCount += 1
|
|
||||||
stopMonitoringSignificantLocationChangesClosure?()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
class CXProviderMock: CXProviderProtocol, @unchecked Sendable {
|
class CXProviderMock: CXProviderProtocol, @unchecked Sendable {
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,13 @@ protocol CLLocationManagerProtocol: AnyObject {
|
|||||||
var showsBackgroundLocationIndicator: Bool { get set }
|
var showsBackgroundLocationIndicator: Bool { get set }
|
||||||
var desiredAccuracy: CLLocationAccuracy { get set }
|
var desiredAccuracy: CLLocationAccuracy { get set }
|
||||||
var distanceFilter: CLLocationDistance { get set }
|
var distanceFilter: CLLocationDistance { get set }
|
||||||
|
var pausesLocationUpdatesAutomatically: Bool { get set }
|
||||||
var authorizationStatus: CLAuthorizationStatus { get }
|
var authorizationStatus: CLAuthorizationStatus { get }
|
||||||
var accuracyAuthorization: CLAccuracyAuthorization { get }
|
var accuracyAuthorization: CLAccuracyAuthorization { get }
|
||||||
|
|
||||||
func requestAlwaysAuthorization()
|
func requestAlwaysAuthorization()
|
||||||
func startUpdatingLocation()
|
func startUpdatingLocation()
|
||||||
func stopUpdatingLocation()
|
func stopUpdatingLocation()
|
||||||
func startMonitoringSignificantLocationChanges()
|
|
||||||
func stopMonitoringSignificantLocationChanges()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CLLocationManager: CLLocationManagerProtocol { }
|
extension CLLocationManager: CLLocationManagerProtocol { }
|
||||||
|
|||||||
@@ -9,12 +9,6 @@ import Combine
|
|||||||
import CoreLocation
|
import CoreLocation
|
||||||
|
|
||||||
class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationManagerDelegate {
|
class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationManagerDelegate {
|
||||||
enum LiveState {
|
|
||||||
case full
|
|
||||||
case limited
|
|
||||||
case off
|
|
||||||
}
|
|
||||||
|
|
||||||
private let clientProxy: ClientProxyProtocol
|
private let clientProxy: ClientProxyProtocol
|
||||||
private let locationManager: CLLocationManagerProtocol
|
private let locationManager: CLLocationManagerProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
@@ -32,7 +26,7 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
private var liveState = LiveState.off
|
private var isUpdatingLocation = false
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
init(clientProxy: ClientProxyProtocol,
|
init(clientProxy: ClientProxyProtocol,
|
||||||
@@ -52,7 +46,13 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
self.locationManager.delegate = self
|
self.locationManager.delegate = self
|
||||||
self.locationManager.allowsBackgroundLocationUpdates = true
|
self.locationManager.allowsBackgroundLocationUpdates = true
|
||||||
self.locationManager.showsBackgroundLocationIndicator = true
|
self.locationManager.showsBackgroundLocationIndicator = true
|
||||||
setupMinimumDistance(appSettings.liveLocationMinimumDistanceUpdate)
|
|
||||||
|
// Since unpausing location updates is not trivial, let's always keep the location updates running
|
||||||
|
// The distance filtering will already take care of not sending updates when not required.
|
||||||
|
// https://developer.apple.com/documentation/corelocation/cllocationmanager/pauseslocationupdatesautomatically
|
||||||
|
self.locationManager.pausesLocationUpdatesAutomatically = false
|
||||||
|
|
||||||
|
setupMinimumDistanceUpdatesAndAccuracy(minimumDistance: appSettings.liveLocationMinimumDistanceUpdate)
|
||||||
setupSubscriptions()
|
setupSubscriptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,18 +125,8 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
stopAllSessions()
|
stopAllSessions()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (liveState, manager.accuracyAuthorization) {
|
// Accuracy authorization may have changed, reapply new accuracy settings.
|
||||||
// If accuracy authorization changed while updates are active, start and stop to switch update method.
|
setupMinimumDistanceUpdatesAndAccuracy(minimumDistance: appSettings.liveLocationMinimumDistanceUpdate)
|
||||||
case (.full, .reducedAccuracy), (.limited, .fullAccuracy):
|
|
||||||
stopUpdatingLocation()
|
|
||||||
if manager.accuracyAuthorization == .fullAccuracy {
|
|
||||||
// The system has forced reduced desired accuracy so we need to restore the desired value by the user.
|
|
||||||
setupMinimumDistance(appSettings.liveLocationMinimumDistanceUpdate)
|
|
||||||
}
|
|
||||||
startUpdatingLocation()
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
authorizationStatusSubject.send(manager.authorizationStatus)
|
authorizationStatusSubject.send(manager.authorizationStatus)
|
||||||
}
|
}
|
||||||
@@ -194,8 +184,8 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
appSettings.$liveLocationMinimumDistanceUpdate
|
appSettings.$liveLocationMinimumDistanceUpdate
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.debounce(for: .seconds(1), scheduler: DispatchQueue.main)
|
.debounce(for: .seconds(1), scheduler: DispatchQueue.main)
|
||||||
.sink { [weak self] minimumDistance in
|
.sink { [weak self] newValue in
|
||||||
self?.setupMinimumDistance(minimumDistance)
|
self?.setupMinimumDistanceUpdatesAndAccuracy(minimumDistance: newValue)
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
@@ -209,42 +199,36 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up the distance filter and the most optimal accuracy given the minimum distance to save battery.
|
/// Sets up the distance filter and the most optimal accuracy given the minimum distance to save battery.
|
||||||
private func setupMinimumDistance(_ minimumDistance: Int) {
|
private func setupMinimumDistanceUpdatesAndAccuracy(minimumDistance: Int) {
|
||||||
switch minimumDistance {
|
if locationManager.accuracyAuthorization == .fullAccuracy {
|
||||||
case 0..<10:
|
switch minimumDistance {
|
||||||
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
case 0..<10:
|
||||||
case 10..<100:
|
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
||||||
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
case 10..<100:
|
||||||
default:
|
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
||||||
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
default:
|
||||||
|
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locationManager.desiredAccuracy = kCLLocationAccuracyReduced
|
||||||
}
|
}
|
||||||
locationManager.distanceFilter = CLLocationDistance(minimumDistance)
|
locationManager.distanceFilter = CLLocationDistance(minimumDistance)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startUpdatingLocation() {
|
private func startUpdatingLocation() {
|
||||||
guard liveState == .off else { return }
|
guard !isUpdatingLocation else { return }
|
||||||
|
|
||||||
if locationManager.accuracyAuthorization == .fullAccuracy {
|
MXLog.info("Starting live location updates")
|
||||||
MXLog.info("Starting live location updates with full accuracy")
|
isUpdatingLocation = true
|
||||||
liveState = .full
|
locationManager.startUpdatingLocation()
|
||||||
locationManager.startUpdatingLocation()
|
|
||||||
} else {
|
|
||||||
MXLog.info("Starting live location updates with significant changes (reduced accuracy)")
|
|
||||||
liveState = .limited
|
|
||||||
locationManager.startMonitoringSignificantLocationChanges()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func stopUpdatingLocation() {
|
private func stopUpdatingLocation() {
|
||||||
if liveState == .full {
|
guard isUpdatingLocation else { return }
|
||||||
MXLog.info("Stopping live location updates (full accuracy)")
|
|
||||||
locationManager.stopUpdatingLocation()
|
|
||||||
} else if liveState == .limited {
|
|
||||||
MXLog.info("Stopping live location updates (reduced accuracy)")
|
|
||||||
locationManager.stopMonitoringSignificantLocationChanges()
|
|
||||||
}
|
|
||||||
|
|
||||||
liveState = .off
|
MXLog.info("Stopping live location updates")
|
||||||
|
locationManager.stopUpdatingLocation()
|
||||||
|
isUpdatingLocation = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendLocationToActiveRooms(_ coordinate: CLLocationCoordinate2D) async {
|
private func sendLocationToActiveRooms(_ coordinate: CLLocationCoordinate2D) async {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
// Please see LICENSE files in the repository root for full details.
|
// Please see LICENSE files in the repository root for full details.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreLocation
|
||||||
@testable import ElementX
|
@testable import ElementX
|
||||||
import Foundation
|
import Foundation
|
||||||
import Testing
|
import Testing
|
||||||
@@ -14,15 +15,10 @@ final class LiveLocationManagerTests {
|
|||||||
private var clientProxy: ClientProxyMock!
|
private var clientProxy: ClientProxyMock!
|
||||||
private var locationManagerMock: CLLocationManagerMock!
|
private var locationManagerMock: CLLocationManagerMock!
|
||||||
private var manager: LiveLocationManager!
|
private var manager: LiveLocationManager!
|
||||||
|
private var appSettings: AppSettings!
|
||||||
private let appSettings: AppSettings
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
AppSettings.resetAllSettings()
|
AppSettings.resetAllSettings()
|
||||||
appSettings = AppSettings()
|
|
||||||
clientProxy = ClientProxyMock(.init())
|
|
||||||
locationManagerMock = CLLocationManagerMock(.init())
|
|
||||||
manager = LiveLocationManager(clientProxy: clientProxy, appSettings: appSettings, locationManager: locationManagerMock)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@@ -33,6 +29,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationWithNoExistingSession() async throws {
|
func startLiveLocationWithNoExistingSession() async throws {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
@@ -43,11 +40,11 @@ final class LiveLocationManagerTests {
|
|||||||
#expect(!roomProxy.stopLiveLocationShareCalled)
|
#expect(!roomProxy.stopLiveLocationShareCalled)
|
||||||
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] != nil)
|
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] != nil)
|
||||||
#expect(locationManagerMock.startUpdatingLocationCalled)
|
#expect(locationManagerMock.startUpdatingLocationCalled)
|
||||||
#expect(!locationManagerMock.startMonitoringSignificantLocationChangesCalled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationWithExistingSessionStopsItFirst() async throws {
|
func startLiveLocationWithExistingSessionStopsItFirst() async throws {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] = Date().addingTimeInterval(300)
|
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] = Date().addingTimeInterval(300)
|
||||||
@@ -71,6 +68,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationDoesNotStopSessionForOtherRoom() async {
|
func startLiveLocationDoesNotStopSessionForOtherRoom() async {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room1:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room1:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
@@ -84,6 +82,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationWhenRoomNotJoined() async {
|
func startLiveLocationWhenRoomNotJoined() async {
|
||||||
|
setUp()
|
||||||
clientProxy.roomForIdentifierClosure = { _ in nil }
|
clientProxy.roomForIdentifierClosure = { _ in nil }
|
||||||
|
|
||||||
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
||||||
@@ -94,6 +93,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationWhenStartShareFails() async {
|
func startLiveLocationWhenStartShareFails() async {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
roomProxy.startLiveLocationShareDurationReturnValue = .failure(.sdkError(RoomProxyMockError.generic))
|
roomProxy.startLiveLocationShareDurationReturnValue = .failure(.sdkError(RoomProxyMockError.generic))
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
@@ -106,6 +106,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationStoresTimeoutDate() async throws {
|
func startLiveLocationStoresTimeoutDate() async throws {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
@@ -125,6 +126,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func stopLiveLocationWhenSessionExists() async {
|
func stopLiveLocationWhenSessionExists() async {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] = Date().addingTimeInterval(300)
|
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] = Date().addingTimeInterval(300)
|
||||||
@@ -136,11 +138,11 @@ final class LiveLocationManagerTests {
|
|||||||
// Setting the timeout date above starts tracking; removing it stops tracking.
|
// Setting the timeout date above starts tracking; removing it stops tracking.
|
||||||
#expect(locationManagerMock.startUpdatingLocationCalled)
|
#expect(locationManagerMock.startUpdatingLocationCalled)
|
||||||
#expect(locationManagerMock.stopUpdatingLocationCalled)
|
#expect(locationManagerMock.stopUpdatingLocationCalled)
|
||||||
#expect(!locationManagerMock.stopMonitoringSignificantLocationChangesCalled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func stopLiveLocationWhenNoSession() async {
|
func stopLiveLocationWhenNoSession() async {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
@@ -151,6 +153,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func stopLiveLocationDoesNotRemoveOtherSessions() async {
|
func stopLiveLocationDoesNotRemoveOtherSessions() async {
|
||||||
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room1:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room1:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room1:matrix.org"] = Date().addingTimeInterval(300)
|
appSettings.liveLocationSharingTimeoutDatesByRoomID["!room1:matrix.org"] = Date().addingTimeInterval(300)
|
||||||
@@ -166,20 +169,19 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationInReducedAccuracyMode() async throws {
|
func startLiveLocationInReducedAccuracyMode() async throws {
|
||||||
locationManagerMock.underlyingAccuracyAuthorization = .reducedAccuracy
|
setUp(accuracyAuthorization: .reducedAccuracy)
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
||||||
try result.get()
|
try result.get()
|
||||||
|
|
||||||
#expect(locationManagerMock.startMonitoringSignificantLocationChangesCalled)
|
#expect(locationManagerMock.startUpdatingLocationCalled)
|
||||||
#expect(!locationManagerMock.startUpdatingLocationCalled)
|
#expect(locationManagerMock.desiredAccuracy == kCLLocationAccuracyReduced)
|
||||||
|
|
||||||
await manager.stopLiveLocation(roomID: "!room:matrix.org")
|
await manager.stopLiveLocation(roomID: "!room:matrix.org")
|
||||||
|
|
||||||
#expect(locationManagerMock.stopMonitoringSignificantLocationChangesCalled)
|
#expect(locationManagerMock.stopUpdatingLocationCalled)
|
||||||
#expect(!locationManagerMock.stopUpdatingLocationCalled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
@@ -190,4 +192,11 @@ final class LiveLocationManagerTests {
|
|||||||
roomProxy.stopLiveLocationShareReturnValue = .success(())
|
roomProxy.stopLiveLocationShareReturnValue = .success(())
|
||||||
return roomProxy
|
return roomProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func setUp(accuracyAuthorization: CLAccuracyAuthorization = .fullAccuracy) {
|
||||||
|
appSettings = AppSettings()
|
||||||
|
clientProxy = ClientProxyMock(.init())
|
||||||
|
locationManagerMock = CLLocationManagerMock(.init(accuracyAuthorization: accuracyAuthorization))
|
||||||
|
manager = LiveLocationManager(clientProxy: clientProxy, appSettings: appSettings, locationManager: locationManagerMock)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user