19
19
#import " MTRDefines_Internal.h"
20
20
#import " MTRDeviceController_Internal.h"
21
21
#import " MTRDevice_XPC.h"
22
- #import " MTRDevice_XPC_Internal.h"
23
22
#import " MTRLogging_Internal.h"
24
23
#import " MTRXPCClientProtocol.h"
25
24
#import " MTRXPCServerProtocol.h"
34
33
35
34
@interface MTRDeviceController_XPC ()
36
35
37
- @property (nonatomic, readwrite, retain) NSUUID * uniqueIdentifier;
38
- @property (nonnull, atomic, readwrite, retain) MTRXPCDeviceControllerParameters * xpcParameters;
39
- @property (atomic, readwrite, assign) NSTimeInterval xpcRetryTimeInterval;
40
- @property (atomic, readwrite, assign) BOOL xpcConnectedOrConnecting;
36
+ @property (nonatomic, retain, readwrite) NSUUID * uniqueIdentifier;
41
37
42
38
@end
43
39
@@ -52,15 +48,7 @@ - (NSXPCInterface *)_interfaceForServerProtocol
52
48
NSXPCInterface * interface = [NSXPCInterface interfaceWithProtocol: @protocol (MTRXPCServerProtocol)];
53
49
54
50
NSSet * allowedClasses = [NSSet setWithArray: @[
55
- [NSString class ],
56
- [NSNumber class ],
57
- [NSData class ],
58
- [NSArray class ],
59
- [NSDictionary class ],
60
- [NSError class ],
61
- [MTRCommandPath class ],
62
- [MTRAttributePath class ],
63
- [NSDate class ],
51
+ [NSString class ], [NSNumber class ], [NSData class ], [NSArray class ], [NSDictionary class ], [NSError class ], [MTRCommandPath class ], [MTRAttributePath class ]
64
52
]];
65
53
66
54
[interface setClasses: allowedClasses
@@ -74,14 +62,7 @@ - (NSXPCInterface *)_interfaceForClientProtocol
74
62
{
75
63
NSXPCInterface * interface = [NSXPCInterface interfaceWithProtocol: @protocol (MTRXPCClientProtocol)];
76
64
NSSet * allowedClasses = [NSSet setWithArray: @[
77
- [NSString class ],
78
- [NSNumber class ],
79
- [NSData class ],
80
- [NSArray class ],
81
- [NSDictionary class ],
82
- [NSError class ],
83
- [MTRAttributePath class ],
84
- [NSDate class ],
65
+ [NSString class ], [NSNumber class ], [NSData class ], [NSArray class ], [NSDictionary class ], [NSError class ], [MTRAttributePath class ]
85
66
]];
86
67
[interface setClasses: allowedClasses
87
68
forSelector: @selector (device:receivedAttributeReport: )
@@ -102,114 +83,6 @@ - (NSXPCInterface *)_interfaceForClientProtocol
102
83
return [self .uniqueIdentifier UUIDString ];
103
84
}
104
85
105
- - (void )_startXPCConnectionRetry
106
- {
107
- if (!self.xpcConnectedOrConnecting ) {
108
- MTR_LOG (" %@: XPC Connection retry - Starting retry for XPC Connection" , self);
109
- self.xpcRetryTimeInterval = 0.5 ;
110
- mtr_weakify (self);
111
-
112
- dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t ) (self.xpcRetryTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{
113
- mtr_strongify (self);
114
- [self _xpcConnectionRetry ];
115
- });
116
- } else {
117
- MTR_LOG (" %@: XPC Connection retry - Not starting retry for XPC Connection, already trying" , self);
118
- }
119
- }
120
-
121
- - (void )_xpcConnectionRetry
122
- {
123
- MTR_LOG (" %@: XPC Connection retry - timer hit" , self);
124
- if (!self.xpcConnectedOrConnecting ) {
125
- if (![self _setupXPCConnection ]) {
126
- #if 0 // FIXME: Not sure why this retry is not working, but I will fix this later
127
- MTR_LOG("%@: XPC Connection retry - Scheduling another retry", self);
128
- self.xpcRetryTimeInterval = self.xpcRetryTimeInterval >= 1 ? self.xpcRetryTimeInterval * 2 : 1;
129
- self.xpcRetryTimeInterval = MIN(60.0, self.xpcRetryTimeInterval);
130
- mtr_weakify(self);
131
-
132
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.xpcRetryTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
133
- mtr_strongify(self);
134
- [self _xpcConnectionRetry];
135
- });
136
- #else
137
- MTR_LOG (" %@: XPC Connection failed retry - bailing" , self);
138
- #endif
139
- } else {
140
- MTR_LOG (" %@: XPC Connection retry - connection attempt successful" , self);
141
- }
142
- } else {
143
- MTR_LOG (" %@: XPC Connection retry - Mid retry, or connected, stopping retry timer" , self);
144
- }
145
- }
146
-
147
- - (BOOL )_setupXPCConnection
148
- {
149
- self.xpcConnection = self.xpcParameters .xpcConnectionBlock ();
150
-
151
- MTR_LOG (" %@ Set up XPC Connection: %@" , self, self.xpcConnection );
152
- if (self.xpcConnection ) {
153
- mtr_weakify (self);
154
- self.xpcConnection .remoteObjectInterface = [self _interfaceForServerProtocol ];
155
-
156
- self.xpcConnection .exportedInterface = [self _interfaceForClientProtocol ];
157
- self.xpcConnection .exportedObject = self;
158
-
159
- self.xpcConnection .interruptionHandler = ^{
160
- mtr_strongify (self);
161
- MTR_LOG_ERROR (" XPC Connection for device controller interrupted: %@" , self.xpcParameters .uniqueIdentifier );
162
- self.xpcConnectedOrConnecting = NO ;
163
- self.xpcConnection = nil ;
164
- [self _startXPCConnectionRetry ];
165
- };
166
-
167
- self.xpcConnection .invalidationHandler = ^{
168
- mtr_strongify (self);
169
- MTR_LOG_ERROR (" XPC Connection for device controller invalidated: %@" , self.xpcParameters .uniqueIdentifier );
170
- self.xpcConnectedOrConnecting = NO ;
171
- self.xpcConnection = nil ;
172
- [self _startXPCConnectionRetry ];
173
- };
174
-
175
- MTR_LOG (" %@ Activating new XPC connection" , self);
176
- [self .xpcConnection activate ];
177
-
178
- [[self .xpcConnection synchronousRemoteObjectProxyWithErrorHandler: ^(NSError * _Nonnull error) {
179
- MTR_LOG_ERROR (" Checkin error: %@" , error);
180
- }] deviceController: self .uniqueIdentifier checkInWithContext: [NSDictionary dictionary ]];
181
-
182
- // FIXME: Trying to kick all the MTRDevices attached to this controller to re-establish connections
183
- // This state needs to be stored properly and re-established at connnection time
184
-
185
- MTR_LOG (" %@ Starting existing NodeID Registration" , self);
186
- for (NSNumber * nodeID in [self .nodeIDToDeviceMap keyEnumerator ]) {
187
- MTR_LOG (" %@ => Registering nodeID: %@" , self, nodeID);
188
- mtr_weakify (self);
189
-
190
- [[self .xpcConnection synchronousRemoteObjectProxyWithErrorHandler: ^(NSError * _Nonnull error) {
191
- mtr_strongify (self);
192
- MTR_LOG_ERROR (" %@ Registration error for device nodeID: %@ : %@" , self, nodeID, error);
193
- }] deviceController: self .uniqueIdentifier registerNodeID: nodeID];
194
- }
195
-
196
- __block BOOL barrierComplete = NO ;
197
-
198
- [self .xpcConnection scheduleSendBarrierBlock: ^{
199
- barrierComplete = YES ;
200
- MTR_LOG (" %@: Barrier complete: %d" , self, barrierComplete);
201
- }];
202
-
203
- MTR_LOG (" %@ Done existing NodeID Registration, barrierComplete: %d" , self, barrierComplete);
204
- self.xpcConnectedOrConnecting = barrierComplete;
205
- } else {
206
- MTR_LOG_ERROR (" %@ Failed to set up XPC Connection" , self);
207
- self.xpcConnectedOrConnecting = NO ;
208
- }
209
-
210
- return (self.xpcConnectedOrConnecting );
211
- }
212
-
213
86
- (nullable instancetype )initWithParameters : (MTRDeviceControllerAbstractParameters *)parameters
214
87
error : (NSError * __autoreleasing *)error
215
88
{
@@ -237,12 +110,30 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete
237
110
return nil ;
238
111
}
239
112
240
- self.xpcParameters = xpcParameters;
113
+ self.xpcConnection = connectionBlock ();
114
+ self.uniqueIdentifier = UUID;
241
115
self.chipWorkQueue = dispatch_queue_create (" MTRDeviceController_XPC_queue" , DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
242
116
self.nodeIDToDeviceMap = [NSMapTable strongToWeakObjectsMapTable ];
243
- self.uniqueIdentifier = UUID;
244
117
245
- if (![self _setupXPCConnection ]) {
118
+ MTR_LOG (" Set up XPC Connection: %@" , self.xpcConnection );
119
+ if (self.xpcConnection ) {
120
+ self.xpcConnection .remoteObjectInterface = [self _interfaceForServerProtocol ];
121
+
122
+ self.xpcConnection .exportedInterface = [self _interfaceForClientProtocol ];
123
+ self.xpcConnection .exportedObject = self;
124
+
125
+ self.xpcConnection .interruptionHandler = ^{
126
+ MTR_LOG_ERROR (" XPC Connection for device controller interrupted: %@" , UUID);
127
+ };
128
+
129
+ self.xpcConnection .invalidationHandler = ^{
130
+ MTR_LOG_ERROR (" XPC Connection for device controller invalidated: %@" , UUID);
131
+ };
132
+
133
+ MTR_LOG (" Activating new XPC connection" );
134
+ [self .xpcConnection activate ];
135
+ } else {
136
+ MTR_LOG_ERROR (" Failed to set up XPC Connection" );
246
137
return nil ;
247
138
}
248
139
}
@@ -268,7 +159,7 @@ - (id)initWithUniqueIdentifier:(NSUUID *)UUID machServiceName:(NSString *)machSe
268
159
self.xpcConnection .exportedObject = self;
269
160
270
161
MTR_LOG (" %s: resuming new XPC connection" );
271
- [self .xpcConnection activate ];
162
+ [self .xpcConnection resume ];
272
163
} else {
273
164
MTR_LOG_ERROR (" Failed to set up XPC Connection" );
274
165
return nil ;
@@ -286,7 +177,13 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N
286
177
os_unfair_lock_assert_owner (self.deviceMapLock );
287
178
288
179
MTRDevice * deviceToReturn = [[MTRDevice_XPC alloc ] initWithNodeID: nodeID controller: self ];
289
- [self .nodeIDToDeviceMap setObject: deviceToReturn forKey: nodeID];
180
+ // If we're not running, don't add the device to our map. That would
181
+ // create a cycle that nothing would break. Just return the device,
182
+ // which will be in exactly the state it would be in if it were created
183
+ // while we were running and then we got shut down.
184
+ if ([self isRunning ]) {
185
+ [self .nodeIDToDeviceMap setObject: deviceToReturn forKey: nodeID];
186
+ }
290
187
MTR_LOG (" %s: returning XPC device for node id %@" , __PRETTY_FUNCTION__, nodeID);
291
188
return deviceToReturn;
292
189
}
@@ -358,14 +255,6 @@ - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID
358
255
[device deviceConfigurationChanged: nodeID];
359
256
}
360
257
361
- - (oneway void )device : (NSNumber *)nodeID internalStateUpdated : (NSDictionary *)dictionary
362
- {
363
- MTRDevice_XPC * device = (MTRDevice_XPC *) [self deviceForNodeID: nodeID];
364
- MTR_LOG (" Received internalStateUpdated: %@ found device: %@" , nodeID, device);
365
-
366
- [device device: nodeID internalStateUpdated: dictionary];
367
- }
368
-
369
258
#pragma mark - MTRDeviceController Protocol Client
370
259
371
260
// Not Supported via XPC
0 commit comments