Signal-iOS/SignalMessaging/environment/AppSetup.m
Michael Kirk 5632bd2d83 Use reference counting to disable proximity monitoring after audio message
Multiple overlapping activities require proximity monitoring (namely,
CallViewController and listening to audio messages).

These activities can overlap arbitrarily, so we use a reference counting
strategy to keep proximity monitoring on as long as one of these activities is
active.
2018-10-26 15:32:12 -06:00

148 lines
8.5 KiB
Objective-C

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "AppSetup.h"
#import "Environment.h"
#import "VersionMigrations.h"
#import <AxolotlKit/SessionCipher.h>
#import <SignalMessaging/OWSDatabaseMigration.h>
#import <SignalMessaging/OWSProfileManager.h>
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/ContactDiscoveryService.h>
#import <SignalServiceKit/OWS2FAManager.h>
#import <SignalServiceKit/OWSBackgroundTask.h>
#import <SignalServiceKit/OWSBatchMessageProcessor.h>
#import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/OWSDisappearingMessagesJob.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/OWSMessageDecrypter.h>
#import <SignalServiceKit/OWSMessageManager.h>
#import <SignalServiceKit/OWSMessageReceiver.h>
#import <SignalServiceKit/OWSOutgoingReceiptManager.h>
#import <SignalServiceKit/OWSReadReceiptManager.h>
#import <SignalServiceKit/OWSStorage.h>
#import <SignalServiceKit/SSKEnvironment.h>
#import <SignalServiceKit/TSSocketManager.h>
NS_ASSUME_NONNULL_BEGIN
@implementation AppSetup
+ (void)setupEnvironmentWithAppSpecificSingletonBlock:(dispatch_block_t)appSpecificSingletonBlock
migrationCompletion:(dispatch_block_t)migrationCompletion
{
OWSAssertDebug(appSpecificSingletonBlock);
OWSAssertDebug(migrationCompletion);
__block OWSBackgroundTask *_Nullable backgroundTask =
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Order matters here.
//
// All of these "singletons" should have any dependencies used in their
// initializers injected.
[[OWSBackgroundTaskManager sharedManager] observeNotifications];
OWSPrimaryStorage *primaryStorage = [[OWSPrimaryStorage alloc] initStorage];
[OWSPrimaryStorage protectFiles];
// AFNetworking (via CFNetworking) spools it's attachments to NSTemporaryDirectory().
// If you receive a media message while the device is locked, the download will fail if the temporary directory
// is NSFileProtectionComplete
BOOL success = [OWSFileSystem protectFileOrFolderAtPath:NSTemporaryDirectory()
fileProtectionType:NSFileProtectionCompleteUntilFirstUserAuthentication];
OWSAssert(success);
OWSPreferences *preferences = [OWSPreferences new];
TSNetworkManager *networkManager = [[TSNetworkManager alloc] initDefault];
OWSContactsManager *contactsManager = [[OWSContactsManager alloc] initWithPrimaryStorage:primaryStorage];
ContactsUpdater *contactsUpdater = [ContactsUpdater new];
OWSMessageSender *messageSender = [[OWSMessageSender alloc] initWithPrimaryStorage:primaryStorage];
OWSProfileManager *profileManager = [[OWSProfileManager alloc] initWithPrimaryStorage:primaryStorage];
OWSMessageManager *messageManager = [[OWSMessageManager alloc] initWithPrimaryStorage:primaryStorage];
OWSBlockingManager *blockingManager = [[OWSBlockingManager alloc] initWithPrimaryStorage:primaryStorage];
OWSIdentityManager *identityManager = [[OWSIdentityManager alloc] initWithPrimaryStorage:primaryStorage];
id<OWSUDManager> udManager = [[OWSUDManagerImpl alloc] initWithPrimaryStorage:primaryStorage];
OWSMessageDecrypter *messageDecrypter = [[OWSMessageDecrypter alloc] initWithPrimaryStorage:primaryStorage];
OWSBatchMessageProcessor *batchMessageProcessor =
[[OWSBatchMessageProcessor alloc] initWithPrimaryStorage:primaryStorage];
OWSMessageReceiver *messageReceiver = [[OWSMessageReceiver alloc] initWithPrimaryStorage:primaryStorage];
TSSocketManager *socketManager = [[TSSocketManager alloc] init];
TSAccountManager *tsAccountManager = [[TSAccountManager alloc] initWithPrimaryStorage:primaryStorage];
OWS2FAManager *ows2FAManager = [[OWS2FAManager alloc] initWithPrimaryStorage:primaryStorage];
OWSDisappearingMessagesJob *disappearingMessagesJob =
[[OWSDisappearingMessagesJob alloc] initWithPrimaryStorage:primaryStorage];
ContactDiscoveryService *contactDiscoveryService = [[ContactDiscoveryService alloc] initDefault];
OWSReadReceiptManager *readReceiptManager =
[[OWSReadReceiptManager alloc] initWithPrimaryStorage:primaryStorage];
OWSOutgoingReceiptManager *outgoingReceiptManager =
[[OWSOutgoingReceiptManager alloc] initWithPrimaryStorage:primaryStorage];
OWSSyncManager *syncManager = [[OWSSyncManager alloc] initDefault];
OWSAudioSession *audioSession = [OWSAudioSession new];
OWSSounds *sounds = [[OWSSounds alloc] initWithPrimaryStorage:primaryStorage];
id<OWSProximityMonitoringManager> proximityMonitoringManager = [OWSProximityMonitoringManagerImpl new];
LockInteractionController *lockInteractionController = [[LockInteractionController alloc] initDefault];
OWSWindowManager *windowManager = [[OWSWindowManager alloc] initDefault];
[Environment setShared:[[Environment alloc] initWithAudioSession:audioSession
lockInteractionController:lockInteractionController
preferences:preferences
proximityMonitoringManager:proximityMonitoringManager
sounds:sounds
windowManager:windowManager]];
[SSKEnvironment setShared:[[SSKEnvironment alloc] initWithContactsManager:contactsManager
messageSender:messageSender
profileManager:profileManager
primaryStorage:primaryStorage
contactsUpdater:contactsUpdater
networkManager:networkManager
messageManager:messageManager
blockingManager:blockingManager
identityManager:identityManager
udManager:udManager
messageDecrypter:messageDecrypter
batchMessageProcessor:batchMessageProcessor
messageReceiver:messageReceiver
socketManager:socketManager
tsAccountManager:tsAccountManager
ows2FAManager:ows2FAManager
disappearingMessagesJob:disappearingMessagesJob
contactDiscoveryService:contactDiscoveryService
readReceiptManager:readReceiptManager
outgoingReceiptManager:outgoingReceiptManager
syncManager:syncManager]];
appSpecificSingletonBlock();
OWSAssertDebug(SSKEnvironment.shared.isComplete);
// Register renamed classes.
[NSKeyedUnarchiver setClass:[OWSUserProfile class] forClassName:[OWSUserProfile collection]];
[NSKeyedUnarchiver setClass:[OWSDatabaseMigration class] forClassName:[OWSDatabaseMigration collection]];
[OWSStorage registerExtensionsWithMigrationBlock:^() {
dispatch_async(dispatch_get_main_queue(), ^{
// Don't start database migrations until storage is ready.
[VersionMigrations performUpdateCheckWithCompletion:^() {
OWSAssertIsOnMainThread();
migrationCompletion();
OWSAssertDebug(backgroundTask);
backgroundTask = nil;
}];
});
}];
});
}
@end
NS_ASSUME_NONNULL_END