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