From 4985693aa2d9cc09c3092f2b2486b6e04f042b1e Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 3 Oct 2024 22:59:27 -0700 Subject: [PATCH] Fixing exception with calling into a dead XPC object (#35908) * Fixing exception with calling into a dead XPC object * Fixing white space * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../Framework/CHIP/MTRDefines_Internal.h | 61 +++++++++++-------- .../Framework/CHIP/MTRDeviceController_XPC.mm | 56 ++++++++++++----- src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 30 +++++---- 3 files changed, 96 insertions(+), 51 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index 5a450ece8ec7f3..71a03aa09184c5 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -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) \ @@ -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) \ @@ -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; \ } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index 6d45de6d01b230..45c675121e3675 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -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 = @[ @@ -202,9 +241,7 @@ - (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 @@ -212,12 +249,7 @@ - (BOOL)_setupXPCConnection 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); @@ -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; } diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 7806546768b4f2..d7a4574f918b76 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -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