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