Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing exception with calling into a dead XPC object #35908

Merged
merged 4 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 37 additions & 24 deletions src/darwin/Framework/CHIP/MTRDefines_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,26 @@ typedef struct {} variable_hidden_by_mtr_hide;

#pragma mark - XPC Defines

#define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \
\
-(TYPE) NAME \
{ \
__block TYPE outValue = DEFAULT_VALUE; \
\
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
\
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX \
GETTER_NAME:^(TYPE returnValue) { \
outValue = returnValue; \
}]; \
\
return outValue; \
#define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \
\
-(TYPE) NAME \
{ \
__block TYPE outValue = DEFAULT_VALUE; \
\
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
\
@try { \
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX \
GETTER_NAME:^(TYPE returnValue) { \
outValue = returnValue; \
}]; \
} @catch (NSException * exception) { \
MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \
outValue = DEFAULT_VALUE; \
} \
return outValue; \
}

#define MTR_SIMPLE_REMOTE_XPC_COMMAND(XPC_CONNECTION, METHOD_SIGNATURE, ADDITIONAL_ARGUMENTS, PREFIX) \
Expand All @@ -91,9 +95,13 @@ typedef struct {} variable_hidden_by_mtr_hide;
{ \
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
\
[[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX ADDITIONAL_ARGUMENTS]; \
@try { \
[[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX ADDITIONAL_ARGUMENTS]; \
} @catch (NSException * exception) { \
MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \
} \
}

#define MTR_COMPLEX_REMOTE_XPC_GETTER(XPC_CONNECTION, SIGNATURE, TYPE, DEFAULT_VALUE, ADDITIONAL_ARGUMENTS, PREFIX) \
Expand All @@ -103,11 +111,16 @@ typedef struct {} variable_hidden_by_mtr_hide;
\
NSXPCConnection * xpcConnection = XPC_CONNECTION; \
\
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \
outValue = returnValue; \
}]; \
@try { \
[[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \
MTR_LOG_ERROR("Error: %@", error); \
}] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \
outValue = returnValue; \
}]; \
} @catch (NSException * exception) { \
MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \
outValue = DEFAULT_VALUE; \
} \
\
return outValue; \
}
Expand Down
56 changes: 42 additions & 14 deletions src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,45 @@ @interface MTRDeviceController_XPC ()

@implementation MTRDeviceController_XPC

#pragma mark - Device Node ID Commands

- (void)_registerNodeID:(NSNumber *)nodeID
{
@try {
[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Register node error: %@ nodeID: %@", error, nodeID);
}] deviceController:self.uniqueIdentifier registerNodeID:nodeID];
} @catch (NSException * exception) {
MTR_LOG_ERROR("Exception registering nodeID: %@", exception);
}
}

- (void)_unregisterNodeID:(NSNumber *)nodeID
{
@try {
[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Unregister node error: %@ nodeID: %@", error, nodeID);
}] deviceController:self.uniqueIdentifier unregisterNodeID:nodeID];
} @catch (NSException * exception) {
MTR_LOG_ERROR("Exception registering nodeID: %@", exception);
}
}

- (void)_checkinWithContext:(NSDictionary *)context
{
@try {
if (!context)
context = [NSDictionary dictionary];

[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Checkin error: %@", error);
}] deviceController:self.uniqueIdentifier checkInWithContext:context];
} @catch (NSException * exception) {
MTR_LOG_ERROR("Exception registering nodeID: %@", exception);
}
}

#pragma mark - XPC
+ (NSMutableSet *)_allowedClasses
{
static NSArray * sBaseAllowedClasses = @[
Expand Down Expand Up @@ -202,22 +241,15 @@ - (BOOL)_setupXPCConnection
MTR_LOG("%@ Activating new XPC connection", self);
[self.xpcConnection activate];

[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Checkin error: %@", error);
}] deviceController:self.uniqueIdentifier checkInWithContext:[NSDictionary dictionary]];
[self _checkinWithContext:[NSDictionary dictionary]];

// FIXME: Trying to kick all the MTRDevices attached to this controller to re-establish connections
// This state needs to be stored properly and re-established at connnection time

MTR_LOG("%@ Starting existing NodeID Registration", self);
for (NSNumber * nodeID in [self.nodeIDToDeviceMap keyEnumerator]) {
MTR_LOG("%@ => Registering nodeID: %@", self, nodeID);
mtr_weakify(self);

[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
mtr_strongify(self);
MTR_LOG_ERROR("%@ Registration error for device nodeID: %@ : %@", self, nodeID, error);
}] deviceController:self.uniqueIdentifier registerNodeID:nodeID];
[self _registerNodeID:nodeID];
}

MTR_LOG("%@ Done existing NodeID Registration", self);
Expand Down Expand Up @@ -308,11 +340,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N
[self.nodeIDToDeviceMap setObject:deviceToReturn forKey:nodeID];
MTR_LOG("%s: returning XPC device for node id %@", __PRETTY_FUNCTION__, nodeID);

mtr_weakify(self);
[[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
mtr_strongify(self);
MTR_LOG_ERROR("%@ Registration error for device nodeID: %@ : %@", self, nodeID, error);
}] deviceController:self.uniqueIdentifier registerNodeID:nodeID];
[self _registerNodeID:nodeID];

return deviceToReturn;
}
Expand Down
30 changes: 17 additions & 13 deletions src/darwin/Framework/CHIP/MTRDevice_XPC.mm
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,23 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID
{
NSXPCConnection * xpcConnection = [(MTRDeviceController_XPC *) [self deviceController] xpcConnection];

[[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Error: %@", error);
}] deviceController:[[self deviceController] uniqueIdentifier]
nodeID:[self nodeID]
invokeCommandWithEndpointID:endpointID
clusterID:clusterID
commandID:commandID
commandFields:commandFields
expectedValues:expectedValues
expectedValueInterval:expectedValueInterval
timedInvokeTimeout:timeout
serverSideProcessingTimeout:serverSideProcessingTimeout
completion:completion];
@try {
[[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
MTR_LOG_ERROR("Error: %@", error);
}] deviceController:[[self deviceController] uniqueIdentifier]
nodeID:[self nodeID]
invokeCommandWithEndpointID:endpointID
clusterID:clusterID
commandID:commandID
commandFields:commandFields
expectedValues:expectedValues
expectedValueInterval:expectedValueInterval
timedInvokeTimeout:timeout
serverSideProcessingTimeout:serverSideProcessingTimeout
completion:completion];
} @catch (NSException * exception) {
MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception);
}
}

// Not Supported via XPC
Expand Down
Loading