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