1// Copyright 2015-present 650 Industries. All rights reserved.
2
3#import "EXKernelServiceRegistry.h"
4#import "EXBranchManager.h"
5#import "EXCachedResourceManager.h"
6#import "EXErrorRecoveryManager.h"
7#import "EXFileSystemManager.h"
8#import "EXGoogleAuthManager.h"
9#import "EXHomeModuleManager.h"
10#import "EXKernelAppRegistry.h"
11#import "EXKernelLinkingManager.h"
12#import "EXKernelService.h"
13#import "EXRemoteNotificationManager.h"
14#import "EXScreenOrientationManager.h"
15#import "EXSensorManager.h"
16#import "EXUpdatesManager.h"
17#import "EXUserNotificationManager.h"
18#import "EXUserNotificationCenter.h"
19
20#import <UMCore/UMModuleRegistryProvider.h>
21
22@interface EXKernelServiceRegistry ()
23
24@property (nonatomic, strong) EXBranchManager *branchManager;
25@property (nonatomic, strong) EXCachedResourceManager *cachedResourceManager;
26@property (nonatomic, strong) EXFileSystemManager *fileSystemManager;
27@property (nonatomic, strong) EXGoogleAuthManager *googleAuthManager;
28@property (nonatomic, strong) EXErrorRecoveryManager *errorRecoveryManager;
29@property (nonatomic, strong) EXHomeModuleManager *homeModuleManager;
30@property (nonatomic, strong) EXKernelLinkingManager *linkingManager;
31@property (nonatomic, strong) EXRemoteNotificationManager *remoteNotificationManager;
32@property (nonatomic, strong) EXScreenOrientationManager *screenOrientationManager;
33@property (nonatomic, strong) EXSensorManager *sensorManager;
34@property (nonatomic, strong) EXUpdatesManager *updatesManager;
35@property (nonatomic, strong) EXUserNotificationManager *notificationsManager;
36@property (nonatomic, strong) EXUserNotificationCenter *notificationCenter;
37@property (nonatomic, strong) NSDictionary<NSString *, id> *allServices;
38
39@end
40
41@implementation EXKernelServiceRegistry
42
43- (instancetype)init
44{
45  if (self = [super init]) {
46    // TODO: init these in some clean way
47    [self branchManager];
48    [self cachedResourceManager];
49    [self errorRecoveryManager];
50    [self remoteNotificationManager];
51    [self linkingManager];
52    [self homeModuleManager];
53    [self screenOrientationManager];
54    [self googleAuthManager];
55    [self sensorManager];
56    [self fileSystemManager];
57    [self updatesManager];
58    [self notificationsManager];
59    [self notificationCenter];
60  }
61  return self;
62}
63
64- (EXBranchManager *)branchManager
65{
66  if (!_branchManager) {
67    _branchManager = [[EXBranchManager alloc] init];
68  }
69  return _branchManager;
70}
71
72- (EXCachedResourceManager *)cachedResourceManager
73{
74  if (!_cachedResourceManager) {
75    _cachedResourceManager = [[EXCachedResourceManager alloc] init];
76  }
77  return _cachedResourceManager;
78}
79
80- (EXRemoteNotificationManager *)remoteNotificationManager
81{
82  if (!_remoteNotificationManager) {
83    _remoteNotificationManager = [[EXRemoteNotificationManager alloc] initWithUserNotificationCenter:[self notificationCenter]];
84  }
85  return _remoteNotificationManager;
86}
87
88- (EXErrorRecoveryManager *)errorRecoveryManager
89{
90  if (!_errorRecoveryManager) {
91    _errorRecoveryManager = [[EXErrorRecoveryManager alloc] init];
92  }
93  return _errorRecoveryManager;
94}
95
96- (EXFileSystemManager *)fileSystemManager
97{
98  if (!_fileSystemManager) {
99    _fileSystemManager = [[EXFileSystemManager alloc] init];
100  }
101  return _fileSystemManager;
102}
103
104- (EXGoogleAuthManager *)googleAuthManager
105{
106  if (!_googleAuthManager) {
107    _googleAuthManager = [[EXGoogleAuthManager alloc] init];
108  }
109  return _googleAuthManager;
110}
111
112- (EXKernelLinkingManager *)linkingManager
113{
114  if (!_linkingManager) {
115    _linkingManager = [[EXKernelLinkingManager alloc] init];
116  }
117  return _linkingManager;
118}
119
120- (EXHomeModuleManager *)homeModuleManager
121{
122  if (!_homeModuleManager) {
123    _homeModuleManager = [[EXHomeModuleManager alloc] init];
124  }
125  return _homeModuleManager;
126}
127
128- (EXScreenOrientationManager *)screenOrientationManager
129{
130  if (!_screenOrientationManager) {
131    _screenOrientationManager = [[EXScreenOrientationManager alloc] init];
132  }
133  return _screenOrientationManager;
134}
135
136- (EXSensorManager *)sensorManager
137{
138  if (!_sensorManager) {
139    _sensorManager = [[EXSensorManager alloc] init];
140  }
141  return _sensorManager;
142}
143
144- (EXUpdatesManager *)updatesManager
145{
146  if (!_updatesManager) {
147    _updatesManager = [[EXUpdatesManager alloc] init];
148  }
149  return _updatesManager;
150}
151
152- (EXUserNotificationManager *)notificationsManager
153{
154  if (!_notificationsManager) {
155    _notificationsManager = [[EXUserNotificationManager alloc] init];
156  }
157  return _notificationsManager;
158}
159
160- (EXUserNotificationCenter *)notificationCenter
161{
162  if (!_notificationCenter) {
163    _notificationCenter = [[EXUserNotificationCenter alloc] init];
164  }
165  return _notificationCenter;
166}
167
168- (NSDictionary *)allServices
169{
170  if (!_allServices) {
171    NSMutableDictionary *result = [NSMutableDictionary dictionary];
172    // Here we have services that must be accessible by our scoped Expo modules
173    // EXVersionManagers pass these modules to scoped modules as an initializer argument
174    //
175    // New modules should access singleton modules via the module registry.
176    // New singleton modules should register themselves in UMModuleRegistryProvider's set
177    // using EX_REGISTER_SINGLETON_MODULE macro.
178    NSArray *registryServices = @[
179                                  self.branchManager,
180                                  self.cachedResourceManager,
181                                  self.errorRecoveryManager,
182                                  self.fileSystemManager,
183                                  self.googleAuthManager,
184                                  self.homeModuleManager,
185                                  self.linkingManager,
186                                  self.remoteNotificationManager,
187                                  self.screenOrientationManager,
188                                  self.sensorManager,
189                                  self.updatesManager,
190                                  self.notificationsManager,
191                                  self.notificationCenter
192                                  ];
193    NSArray *allServices = [registryServices arrayByAddingObjectsFromArray:[[UMModuleRegistryProvider singletonModules] allObjects]];
194    for (id service in allServices) {
195      NSString *className = NSStringFromClass([service class]);
196      result[className] = service;
197    }
198    _allServices = result;
199  }
200  return _allServices;
201}
202
203#pragma mark - app registry delegate
204
205- (void)appRegistry:(EXKernelAppRegistry *)registry didRegisterAppRecord:(EXKernelAppRecord *)appRecord
206{
207  [self.allServices enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull className, id  _Nonnull service, BOOL * _Nonnull stop) {
208    if ([service respondsToSelector:@selector(kernelDidRegisterAppWithRecord:)]) {
209      [service kernelDidRegisterAppWithRecord:appRecord];
210    }
211  }];
212}
213
214- (void)appRegistry:(EXKernelAppRegistry *)registry willUnregisterAppRecord:(EXKernelAppRecord *)appRecord
215{
216  [self.allServices enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull className, id  _Nonnull service, BOOL * _Nonnull stop) {
217    if ([service respondsToSelector:@selector(kernelWillUnregisterAppWithRecord:)]) {
218      [service kernelWillUnregisterAppWithRecord:appRecord];
219    }
220  }];
221}
222
223@end
224