Skip to content

Commit 1e58f96

Browse files
kiel-applerestyled-commitswoody-apple
authoredAug 17, 2024··
[Darwin] New XPC Service (#34961)
* empty xpc service files * XPC service needs to be C++ to use MTRLogging * add tests; stub method signature * start configuring test XPC listener * add first test method to XPC service protocol * tests: remove peformance test; add headers * make MTRXPCService testable * more working lines of XPC listener setup * add dummy XPC service for testing * add replying method to service protocol / implementation * remove log - reply contents can be asserted * make test interesting * linty formatty * remove personal development team from pbxproj * fix new file headers * less whitespace * Restyled by whitespace * Restyled by clang-format * add new XPC device controller * sketch out a first XPC method * store WIP for rebase * fix pbxproj merge mistake * make WIP slightly more sensible * WIP: remote proxy obj in `MTRDeviceController_XPC` * more experiments * WIP: return type issue run `MTRXPCServiceTests testMTRXPCServiceSetup` and see selection of proxy object method in `MTRDeviceController_XPC.m`/`initWithXPCListenerEndpointForTesting` around line 44 to see the problem. * add `MTRDevice_XPC` nothing exciting yet * add device controller over XPC parameters stub * add init split for XPC device controllers not yet implemented, but there * rename new XPC parameters class `OverXPC` is already taken / means something else * Restyled by whitespace * Restyled by clang-format * remove failing exploratory test * lintfix * Examples * quickly attempt to fix test unused variable -> warning -> error * Restyled by whitespace * Restyled by clang-format * inevitably the file will need to be obj-C++ * prepare to use mach service name to create XPC connection * allow for other XPC controller connection types for now once mach service is working, i don't expect to need others, but easier to collapse classes than raise. * constant for well-known matter plugin service name * note to self and re-ordering of this code now what `XPCParameters` is a subclass * XPC parameters should support secure coding * don't keep around object proxy; make a new one when needed. try calling the `checkIn` method when connecting. remove old test methods that served their purpose. * that doesn't need to be there. * Restyled by whitespace * Restyled by clang-format * no longer fighting with compiler, have some `instancetype` * extremely normal object construction * somehow this header got thrown out * Restyled by whitespace * Restyled by clang-format * Updating XPC interfaces * hide `initWithMachServiceName:options:` constructor tvOS/iOS compilation issues need a look * make `MTRDeviceController_XPC` an XPC client via `MTRXPCClientProtocol_MTRDeviceController`, which for the moment is empty * remove initial tests they served their purpose well but are no longer relevant * call mach service constructor when appropriate also logging * remove some obsolete test methods * more obsoletes fixed * more obsolete removal and logging tweaks * buildability tweaks * Moving along * Fixing header * Fixing macros and codable * Adding invoke? * Restyled by whitespace * Restyled by clang-format * Actually hooking up to XPCConnection * Actually hooking up to XPCConnection * Adding XPC Parameters * Adding XPC Parameter hookup * Restyled by whitespace * Restyled by clang-format * true => YES --------- Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Justin Wood <woody@apple.com>
1 parent ebc2576 commit 1e58f96

18 files changed

+872
-38
lines changed
 

‎src/darwin/Framework/CHIP/MTRCluster.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4))
7373
* treated as if a default-initialized object was passed in.
7474
*/
7575
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
76-
@interface MTRWriteParams : NSObject <NSCopying>
76+
@interface MTRWriteParams : NSObject <NSCopying, NSSecureCoding>
7777

7878
/**
7979
* Controls whether the write is a timed write.
@@ -109,7 +109,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
109109
* treated as if a default-initialized object was passed in.
110110
*/
111111
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
112-
@interface MTRReadParams : NSObject <NSCopying>
112+
@interface MTRReadParams : NSObject <NSCopying, NSSecureCoding>
113113

114114
/**
115115
* Whether the read/subscribe is fabric-filtered. The default is YES.
@@ -152,7 +152,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
152152
* treated as if a default-initialized object was passed in.
153153
*/
154154
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
155-
@interface MTRSubscribeParams : MTRReadParams
155+
@interface MTRSubscribeParams : MTRReadParams <NSCopying, NSSecureCoding>
156156

157157
/**
158158
* Whether the subscribe should replace already-existing

‎src/darwin/Framework/CHIP/MTRCluster.mm

+123
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ - (instancetype)init
6969
return self;
7070
}
7171

72+
#pragma mark - Copying
73+
7274
- (id)copyWithZone:(NSZone * _Nullable)zone
7375
{
7476
auto other = [[MTRWriteParams alloc] init];
@@ -77,6 +79,38 @@ - (id)copyWithZone:(NSZone * _Nullable)zone
7779
return other;
7880
}
7981

82+
#pragma mark - Coding
83+
84+
+ (BOOL)supportsSecureCoding
85+
{
86+
return YES;
87+
}
88+
89+
static NSString * sTimedWriteTimeoutCodingKey = @"sTimedWriteTimeoutKey";
90+
static NSString * sDataVersionCodingKey = @"sDataVersionKey";
91+
92+
- (nullable instancetype)initWithCoder:(NSCoder *)decoder
93+
{
94+
self = [super init];
95+
96+
if (self == nil) {
97+
return nil;
98+
}
99+
100+
self.timedWriteTimeout = [decoder decodeObjectOfClass:[NSNumber class] forKey:sTimedWriteTimeoutCodingKey];
101+
self.dataVersion = [decoder decodeObjectOfClass:[NSNumber class] forKey:sDataVersionCodingKey];
102+
103+
return self;
104+
}
105+
106+
- (void)encodeWithCoder:(NSCoder *)coder
107+
{
108+
if (self.timedWriteTimeout)
109+
[coder encodeObject:self.timedWriteTimeout forKey:sTimedWriteTimeoutCodingKey];
110+
if (self.dataVersion)
111+
[coder encodeObject:self.dataVersion forKey:sDataVersionCodingKey];
112+
}
113+
80114
@end
81115

82116
@implementation MTRReadParams
@@ -89,6 +123,43 @@ - (instancetype)init
89123
return self;
90124
}
91125

126+
#pragma mark - Coding
127+
128+
+ (BOOL)supportsSecureCoding
129+
{
130+
return YES;
131+
}
132+
133+
static NSString * sFilterByFabricCoderKey = @"sFilterByFabricKey";
134+
static NSString * sMinEventNumberCoderKey = @"sMinEventNumberKey";
135+
static NSString * sAssumeUnknownAttributesReportableCoderKey = @"sAssumeUnknownAttributesReportableKey";
136+
137+
- (nullable instancetype)initWithCoder:(NSCoder *)decoder
138+
{
139+
self = [super init];
140+
141+
if (self == nil) {
142+
return nil;
143+
}
144+
145+
self.filterByFabric = [decoder decodeBoolForKey:sFilterByFabricCoderKey];
146+
self.assumeUnknownAttributesReportable = [decoder decodeBoolForKey:sAssumeUnknownAttributesReportableCoderKey];
147+
self.minEventNumber = [decoder decodeObjectOfClass:[NSNumber class] forKey:sMinEventNumberCoderKey];
148+
149+
return self;
150+
}
151+
152+
- (void)encodeWithCoder:(NSCoder *)coder
153+
{
154+
[coder encodeBool:self.filterByFabric forKey:sFilterByFabricCoderKey];
155+
[coder encodeBool:self.assumeUnknownAttributesReportable forKey:sAssumeUnknownAttributesReportableCoderKey];
156+
157+
if (self.minEventNumber)
158+
[coder encodeObject:self.minEventNumber forKey:sMinEventNumberCoderKey];
159+
}
160+
161+
#pragma mark - Copying
162+
92163
- (id)copyWithZone:(NSZone * _Nullable)zone
93164
{
94165
auto other = [[MTRReadParams alloc] init];
@@ -98,6 +169,8 @@ - (id)copyWithZone:(NSZone * _Nullable)zone
98169
return other;
99170
}
100171

172+
#pragma mark - Other
173+
101174
- (void)toReadPrepareParams:(chip::app::ReadPrepareParams &)readPrepareParams
102175
{
103176
readPrepareParams.mIsFabricFiltered = self.filterByFabric;
@@ -121,18 +194,68 @@ - (instancetype)initWithMinInterval:(NSNumber *)minInterval maxInterval:(NSNumbe
121194
return self;
122195
}
123196

197+
#pragma mark - Copying
124198
- (id)copyWithZone:(NSZone * _Nullable)zone
125199
{
126200
auto other = [[MTRSubscribeParams alloc] initWithMinInterval:self.minInterval maxInterval:self.maxInterval];
201+
127202
other.filterByFabric = self.filterByFabric;
128203
other.minEventNumber = self.minEventNumber;
129204
other.assumeUnknownAttributesReportable = self.assumeUnknownAttributesReportable;
130205
other.replaceExistingSubscriptions = self.replaceExistingSubscriptions;
131206
other.reportEventsUrgently = self.reportEventsUrgently;
132207
other.resubscribeAutomatically = self.resubscribeAutomatically;
208+
other.minInterval = self.minInterval;
209+
other.maxInterval = self.maxInterval;
210+
133211
return other;
134212
}
135213

214+
#pragma mark - Coding
215+
+ (BOOL)supportsSecureCoding
216+
{
217+
return YES;
218+
}
219+
220+
static NSString * sReplaceExistingSubscriptionsCoderKey = @"sFilterByFabricKey";
221+
static NSString * sReportEventsUrgentlyCoderKey = @"sMinEventNumberKey";
222+
static NSString * sResubscribeAutomaticallyCoderKey = @"sAssumeUnknownAttributesReportableKey";
223+
static NSString * sMinIntervalKeyCoderKey = @"sMinIntervalKeyKey";
224+
static NSString * sMaxIntervalKeyCoderKey = @"sMaxIntervalKeyKey";
225+
226+
- (nullable instancetype)initWithCoder:(NSCoder *)decoder
227+
{
228+
self = [super initWithCoder:decoder];
229+
230+
if (self == nil) {
231+
return nil;
232+
}
233+
234+
self.replaceExistingSubscriptions = [decoder decodeBoolForKey:sReplaceExistingSubscriptionsCoderKey];
235+
self.reportEventsUrgently = [decoder decodeBoolForKey:sReportEventsUrgentlyCoderKey];
236+
self.resubscribeAutomatically = [decoder decodeBoolForKey:sResubscribeAutomaticallyCoderKey];
237+
self.minInterval = [decoder decodeObjectOfClass:[NSNumber class] forKey:sMinIntervalKeyCoderKey];
238+
self.maxInterval = [decoder decodeObjectOfClass:[NSNumber class] forKey:sMaxIntervalKeyCoderKey];
239+
240+
return self;
241+
}
242+
243+
- (void)encodeWithCoder:(NSCoder *)coder
244+
{
245+
[super encodeWithCoder:coder];
246+
247+
[coder encodeBool:self.replaceExistingSubscriptions forKey:sReplaceExistingSubscriptionsCoderKey];
248+
[coder encodeBool:self.reportEventsUrgently forKey:sReportEventsUrgentlyCoderKey];
249+
[coder encodeBool:self.resubscribeAutomatically forKey:sResubscribeAutomaticallyCoderKey];
250+
251+
if (self.minInterval)
252+
[coder encodeObject:self.minInterval forKey:sMinIntervalKeyCoderKey];
253+
if (self.maxInterval)
254+
[coder encodeObject:self.maxInterval forKey:sMaxIntervalKeyCoderKey];
255+
}
256+
257+
#pragma mark - Main
258+
136259
- (void)toReadPrepareParams:(chip::app::ReadPrepareParams &)readPrepareParams
137260
{
138261
[super toReadPrepareParams:readPrepareParams];

‎src/darwin/Framework/CHIP/MTRDefines_Internal.h

+47
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,50 @@ typedef struct {} variable_hidden_by_mtr_hide;
6464

6565
// Default timed interaction timeout, in ms, if another one is not provided.
6666
#define MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS 10000
67+
68+
#pragma mark - XPC Defines
69+
70+
#define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \
71+
\
72+
-(TYPE) NAME \
73+
{ \
74+
__block TYPE outValue = DEFAULT_VALUE; \
75+
\
76+
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
77+
\
78+
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
79+
MTR_LOG_ERROR("Error: %@", error); \
80+
}] PREFIX \
81+
GETTER_NAME:^(TYPE returnValue) { \
82+
outValue = returnValue; \
83+
}]; \
84+
\
85+
return outValue; \
86+
}
87+
88+
#define MTR_SIMPLE_REMOTE_XPC_COMMAND(XPC_CONNECTION, METHOD_SIGNATURE, ADDITIONAL_ARGUMENTS, PREFIX) \
89+
\
90+
-(void) METHOD_SIGNATURE \
91+
{ \
92+
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
93+
\
94+
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
95+
MTR_LOG_ERROR("Error: %@", error); \
96+
}] PREFIX ADDITIONAL_ARGUMENTS]; \
97+
}
98+
99+
#define MTR_COMPLEX_REMOTE_XPC_GETTER(XPC_CONNECTION, SIGNATURE, TYPE, DEFAULT_VALUE, ADDITIONAL_ARGUMENTS, PREFIX) \
100+
-(TYPE) SIGNATURE \
101+
{ \
102+
__block TYPE outValue = DEFAULT_VALUE; \
103+
\
104+
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
105+
\
106+
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
107+
MTR_LOG_ERROR("Error: %@", error); \
108+
}] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \
109+
outValue = returnValue; \
110+
}]; \
111+
\
112+
return outValue; \
113+
}

‎src/darwin/Framework/CHIP/MTRDeviceController.mm

+6-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#import "MTRDeviceControllerLocalTestStorage.h"
3232
#import "MTRDeviceControllerStartupParams.h"
3333
#import "MTRDeviceControllerStartupParams_Internal.h"
34+
#import "MTRDeviceController_XPC.h"
3435
#import "MTRDevice_Concrete.h"
3536
#import "MTRDevice_Internal.h"
3637
#import "MTRError_Internal.h"
@@ -144,7 +145,11 @@ - (instancetype)initForSubclasses
144145

145146
- (nullable MTRDeviceController *)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error
146147
{
147-
if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) {
148+
if ([parameters isKindOfClass:MTRXPCDeviceControllerParameters.class]) {
149+
MTRXPCDeviceControllerParameters * resolvedParameters = (MTRXPCDeviceControllerParameters *) parameters;
150+
MTR_LOG("Starting up with XPC Device Controller Parameters: %@", parameters);
151+
return [[MTRDeviceController_XPC alloc] initWithUniqueIdentifier:resolvedParameters.uniqueIdentifier xpConnectionBlock:resolvedParameters.xpcConnectionBlock];
152+
} else if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) {
148153
MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters);
149154
if (error) {
150155
*error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];

‎src/darwin/Framework/CHIP/MTRDeviceControllerParameters.h

+22
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,26 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6))
145145

146146
@end
147147

148+
MTR_NEWLY_AVAILABLE
149+
@interface MTRXPCDeviceControllerParameters : MTRDeviceControllerAbstractParameters
150+
151+
- (instancetype)init NS_UNAVAILABLE;
152+
+ (instancetype)new NS_UNAVAILABLE;
153+
154+
/**
155+
* A controller created from this way will connect to a remote instance of an MTRDeviceController loaded in an XPC Service
156+
*
157+
* @param xpcConnectionBlock The XPC Connection block that will return an NSXPCConnection to the indended listener.
158+
*
159+
* @param uniqueIdentifier The unique id to assign to the controller.
160+
*
161+
*/
162+
- (instancetype)initWithXPConnectionBlock:(NSXPCConnection * (^)(void) )xpcConnectionBlock
163+
uniqueIdentifier:(NSUUID *)uniqueIdentifier;
164+
165+
@property (atomic, readonly, retain) NSUUID * uniqueIdentifier MTR_NEWLY_AVAILABLE;
166+
@property (readonly, strong, nonatomic) NSXPCConnection * (^xpcConnectionBlock)(void) MTR_NEWLY_AVAILABLE;
167+
168+
@end
169+
148170
NS_ASSUME_NONNULL_END

‎src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm

+17
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,23 @@ - (instancetype)initWithStorageDelegate:(id<MTRDeviceControllerStorageDelegate>)
331331
}
332332
@end
333333

334+
@implementation MTRXPCDeviceControllerParameters
335+
336+
@synthesize uniqueIdentifier = _uniqueIdentifier;
337+
@synthesize xpcConnectionBlock = _xpcConnectionBlock;
338+
339+
- (instancetype)initWithXPConnectionBlock:(NSXPCConnection * (^)(void) )xpcConnectionBlock
340+
uniqueIdentifier:(NSUUID *)uniqueIdentifier;
341+
{
342+
if (self = [super _initInternal]) {
343+
_xpcConnectionBlock = [xpcConnectionBlock copy];
344+
_uniqueIdentifier = [uniqueIdentifier copy];
345+
}
346+
347+
return self;
348+
}
349+
@end
350+
334351
@implementation MTRDeviceControllerStartupParamsInternal
335352

336353
- (instancetype)initWithParams:(MTRDeviceControllerStartupParams *)params
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (c) 2024 Project CHIP Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import <Matter/Matter.h>
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
@interface MTRDeviceControllerXPCParameters : MTRDeviceControllerParameters
22+
@end
23+
24+
@interface MTRDeviceControllerMachServiceXPCParameters : MTRDeviceControllerXPCParameters
25+
26+
@property (atomic, retain) NSString * machServiceName;
27+
@property (atomic, readwrite) NSXPCConnectionOptions connectionOptions;
28+
29+
@end
30+
31+
NS_ASSUME_NONNULL_END
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) 2024 Project CHIP Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "MTRDeviceControllerXPCParameters.h"
18+
19+
@implementation MTRDeviceControllerXPCParameters
20+
21+
+ (BOOL)supportsSecureCoding
22+
{
23+
return YES;
24+
}
25+
26+
@end
27+
28+
@implementation MTRDeviceControllerMachServiceXPCParameters
29+
30+
+ (BOOL)supportsSecureCoding
31+
{
32+
return YES;
33+
}
34+
35+
@end

0 commit comments

Comments
 (0)
Please sign in to comment.