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