[Darwin] Fix Matter framework delegates to pass the delegating object as the first arg to their methods (#23665)
* [Darwin] Fix Matter framework delegates to pass the delegating object as the first arg to their methods
This is a re-landing of PR #22682 and PR #22690 but with backwards
compat shims in place.
The changes to MTRDeviceControllerDelegate are OK because this
protocol is newly introduced and has not shipped yet.
* Address review comment.
Co-authored-by: Jeff Tung <100387939+jtung-apple@users.noreply.github.com>
diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.h b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.h
index 7d62b1b..334d233 100644
--- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.h
+++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.h
@@ -20,13 +20,15 @@
#import <Matter/Matter.h>
+@class MTRDeviceController;
+
@interface CHIPToolDeviceControllerDelegate : NSObject <MTRDeviceControllerDelegate>
@property PairingCommandBridge * commandBridge;
@property chip::NodeId deviceID;
@property MTRDeviceController * commissioner;
@property MTRCommissioningParameters * params;
-- (void)onCommissioningSessionEstablishmentDone:(NSError *)error;
-- (void)onCommissioningComplete:(NSError *)error;
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError *)error;
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError *)error;
@end
diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm
index 06dd78a..dc53280 100644
--- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm
+++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm
@@ -44,7 +44,7 @@
}
}
-- (void)onCommissioningSessionEstablishmentDone:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError *)error
{
if (error != nil) {
ChipLogProgress(chipTool, "PASE establishment failed");
@@ -61,7 +61,7 @@
}
}
-- (void)onCommissioningComplete:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError *)error
{
_commandBridge->SetCommandExitStatus(error, "Pairing Commissioning Complete");
}
diff --git a/examples/darwin-framework-tool/commands/tests/TestCommandBridge.h b/examples/darwin-framework-tool/commands/tests/TestCommandBridge.h
index 8f03198..3873ea8 100644
--- a/examples/darwin-framework-tool/commands/tests/TestCommandBridge.h
+++ b/examples/darwin-framework-tool/commands/tests/TestCommandBridge.h
@@ -48,9 +48,9 @@
@property chip::NodeId deviceId;
@property BOOL active; // Whether to pass on notifications to the commandBridge
-- (void)onStatusUpdate:(MTRCommissioningStatus)status;
-- (void)onCommissioningSessionEstablishmentDone:(NSError * _Nullable)error;
-- (void)onCommissioningComplete:(NSError * _Nullable)error;
+- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status;
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error;
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithTestCommandBridge:(TestCommandBridge *)commandBridge;
@@ -529,7 +529,7 @@
NS_ASSUME_NONNULL_BEGIN
@implementation TestDeviceControllerDelegate
-- (void)onStatusUpdate:(MTRCommissioningStatus)status
+- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status
{
if (_active) {
if (status == MTRCommissioningStatusSuccess) {
@@ -542,7 +542,7 @@
}
}
-- (void)onCommissioningSessionEstablishmentDone:(NSError * _Nullable)error
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error
{
if (_active) {
if (error != nil) {
@@ -556,7 +556,7 @@
}
}
-- (void)onCommissioningComplete:(NSError * _Nullable)error
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error
{
if (_active) {
_active = NO;
diff --git a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegate.h b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegate.h
index 9f30053..d54fdeb 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegate.h
+++ b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegate.h
@@ -39,10 +39,10 @@
/**
* Only one of the following delegate callbacks should be implemented.
*
- * If -deviceAttestation:failedForDevice:error: is implemented, then it will be called when device
+ * If -deviceAttestationFailedForController:device:error: is implemented, then it will be called when device
* attestation fails, and the client can decide to continue or stop the commissioning.
*
- * If -deviceAttestation:completedForDevice:attestationDeviceInfo:error: is implemented, then it
+ * If -deviceAttestationCompletedForController:device:attestationDeviceInfo:error: is implemented, then it
* will always be called when device attestation completes.
*/
@@ -58,10 +58,10 @@
* @param attestationDeviceInfo Attestation information for the device
* @param error NSError representing the error code on attestation failure. Nil if success.
*/
-- (void)deviceAttestation:(MTRDeviceController *)controller
- completedForDevice:(void *)device
- attestationDeviceInfo:(MTRDeviceAttestationDeviceInfo *)attestationDeviceInfo
- error:(NSError * _Nullable)error;
+- (void)deviceAttestationCompletedForController:(MTRDeviceController *)controller
+ device:(void *)device
+ attestationDeviceInfo:(MTRDeviceAttestationDeviceInfo *)attestationDeviceInfo
+ error:(NSError * _Nullable)error MTR_NEWLY_AVAILABLE;
/**
* Notify the delegate when device attestation fails
@@ -70,7 +70,20 @@
* @param device Handle of device being commissioned
* @param error NSError representing the error code for the failure
*/
-- (void)deviceAttestation:(MTRDeviceController *)controller failedForDevice:(void *)device error:(NSError * _Nonnull)error;
+- (void)deviceAttestationFailedForController:(MTRDeviceController *)controller
+ device:(void *)device
+ error:(NSError * _Nonnull)error MTR_NEWLY_AVAILABLE;
+
+- (void)deviceAttestation:(MTRDeviceController *)controller
+ completedForDevice:(void *)device
+ attestationDeviceInfo:(MTRDeviceAttestationDeviceInfo *)attestationDeviceInfo
+ error:(NSError * _Nullable)error
+ MTR_NEWLY_DEPRECATED("Please implement deviceAttestationCompletedForController:device:attestationDeviceInfo:error:");
+
+- (void)deviceAttestation:(MTRDeviceController *)controller
+ failedForDevice:(void *)device
+ error:(NSError * _Nonnull)error
+ MTR_NEWLY_DEPRECATED("Please implement deviceAttestationFailedForController:device:error:");
@end
diff --git a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm
index 528148d..4a489aa 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm
@@ -30,7 +30,9 @@
mResult = attestationResult;
id<MTRDeviceAttestationDelegate> strongDelegate = mDeviceAttestationDelegate;
- if ([strongDelegate respondsToSelector:@selector(deviceAttestation:completedForDevice:attestationDeviceInfo:error:)]) {
+ if ([strongDelegate respondsToSelector:@selector(deviceAttestationCompletedForController:
+ device:attestationDeviceInfo:error:)]
+ || [strongDelegate respondsToSelector:@selector(deviceAttestation:completedForDevice:attestationDeviceInfo:error:)]) {
MTRDeviceController * strongController = mDeviceController;
if (strongController) {
NSData * dacData = AsData(info.dacDerBuffer());
@@ -43,18 +45,31 @@
NSError * error = (attestationResult == chip::Credentials::AttestationVerificationResult::kSuccess)
? nil
: [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTEGRITY_CHECK_FAILED];
- [strongDelegate deviceAttestation:mDeviceController
- completedForDevice:device
- attestationDeviceInfo:deviceInfo
- error:error];
+ if ([strongDelegate respondsToSelector:@selector
+ (deviceAttestationCompletedForController:device:attestationDeviceInfo:error:)]) {
+ [strongDelegate deviceAttestationCompletedForController:mDeviceController
+ device:device
+ attestationDeviceInfo:deviceInfo
+ error:error];
+ } else {
+ [strongDelegate deviceAttestation:mDeviceController
+ completedForDevice:device
+ attestationDeviceInfo:deviceInfo
+ error:error];
+ }
}
- } else if ((attestationResult != chip::Credentials::AttestationVerificationResult::kSuccess) &&
- [strongDelegate respondsToSelector:@selector(deviceAttestation:failedForDevice:error:)]) {
+ } else if ((attestationResult != chip::Credentials::AttestationVerificationResult::kSuccess)
+ && ([strongDelegate respondsToSelector:@selector(deviceAttestationFailedForController:device:error:)] ||
+ [strongDelegate respondsToSelector:@selector(deviceAttestation:failedForDevice:error:)])) {
MTRDeviceController * strongController = mDeviceController;
if (strongController) {
NSError * error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTEGRITY_CHECK_FAILED];
- [strongDelegate deviceAttestation:mDeviceController failedForDevice:device error:error];
+ if ([strongDelegate respondsToSelector:@selector(deviceAttestationFailedForController:device:error:)]) {
+ [strongDelegate deviceAttestationFailedForController:mDeviceController device:device error:error];
+ } else {
+ [strongDelegate deviceAttestation:mDeviceController failedForDevice:device error:error];
+ }
}
}
});
diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm
index c183353..c872221 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceController.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm
@@ -433,6 +433,8 @@
}
BOOL shouldWaitAfterDeviceAttestation = NO;
if ([commissioningParams.deviceAttestationDelegate
+ respondsToSelector:@selector(deviceAttestationCompletedForController:device:attestationDeviceInfo:error:)]
+ || [commissioningParams.deviceAttestationDelegate
respondsToSelector:@selector(deviceAttestation:completedForDevice:attestationDeviceInfo:error:)]) {
shouldWaitAfterDeviceAttestation = YES;
}
@@ -542,7 +544,7 @@
dispatch_async(_chipWorkQueue, ^{
VerifyOrReturn([self checkIsRunning]);
- self->_deviceControllerDelegateBridge->setDelegate(delegate, queue);
+ self->_deviceControllerDelegateBridge->setDelegate(self, delegate, queue);
});
}
@@ -843,35 +845,32 @@
- (BOOL)respondsToSelector:(SEL)selector
{
- // This logic will need to change a bit when the MTRDeviceControllerDelegate
- // signatures change. It's shaped the way it is to make those changes
- // easier.
- if (selector == @selector(onStatusUpdate:)) {
+ if (selector == @selector(controller:statusUpdate:)) {
return [self.delegate respondsToSelector:@selector(onStatusUpdate:)];
}
- if (selector == @selector(onCommissioningSessionEstablishmentDone:)) {
+ if (selector == @selector(controller:commissioningSessionEstablishmentDone:)) {
return [self.delegate respondsToSelector:@selector(onPairingComplete:)];
}
- if (selector == @selector(onCommissioningComplete:)) {
+ if (selector == @selector(controller:commissioningComplete:)) {
return [self.delegate respondsToSelector:@selector(onCommissioningComplete:)];
}
return [super respondsToSelector:selector];
}
-- (void)onStatusUpdate:(MTRCommissioningStatus)status
+- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status
{
[self.delegate onStatusUpdate:static_cast<MTRPairingStatus>(status)];
}
-- (void)onCommissioningSessionEstablishmentDone:(NSError * _Nullable)error
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error
{
[self.delegate onPairingComplete:error];
}
-- (void)onCommissioningComplete:(NSError * _Nullable)error
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error
{
[self.delegate onCommissioningComplete:error];
}
diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h
index 3b549c4..d955c65 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h
+++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h
@@ -26,6 +26,8 @@
MTRCommissioningStatusDiscoveringMoreDevices = 3
} MTR_NEWLY_AVAILABLE;
+@class MTRDeviceController;
+
/**
* The protocol definition for the MTRDeviceControllerDelegate.
*
@@ -37,18 +39,18 @@
/**
* Notify the delegate when commissioning status gets updated.
*/
-- (void)onStatusUpdate:(MTRCommissioningStatus)status;
+- (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status;
/**
* Notify the delegate when a commissioning session is established or the
* establishment has errored out.
*/
-- (void)onCommissioningSessionEstablishmentDone:(NSError * _Nullable)error;
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError * _Nullable)error;
/**
* Notify the delegate when commissioning is completed.
*/
-- (void)onCommissioningComplete:(NSError * _Nullable)error;
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError * _Nullable)error;
@end
diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.h
index 299e85b..464f0c9 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.h
+++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.h
@@ -22,13 +22,14 @@
NS_ASSUME_NONNULL_BEGIN
-class MTRDeviceControllerDelegateBridge : public chip::Controller::DevicePairingDelegate
-{
+@class MTRDeviceController;
+
+class MTRDeviceControllerDelegateBridge : public chip::Controller::DevicePairingDelegate {
public:
MTRDeviceControllerDelegateBridge();
~MTRDeviceControllerDelegateBridge();
- void setDelegate(id<MTRDeviceControllerDelegate> delegate, dispatch_queue_t queue);
+ void setDelegate(MTRDeviceController * controller, id<MTRDeviceControllerDelegate> delegate, dispatch_queue_t queue);
void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override;
@@ -39,6 +40,7 @@
void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR error) override;
private:
+ MTRDeviceController * __weak mController;
_Nullable id<MTRDeviceControllerDelegate> mDelegate;
_Nullable dispatch_queue_t mQueue;
diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm
index f84a99e..3ac0883 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm
@@ -16,6 +16,7 @@
*/
#import "MTRDeviceControllerDelegateBridge.h"
+#import "MTRDeviceController.h"
#import "MTRError_Internal.h"
MTRDeviceControllerDelegateBridge::MTRDeviceControllerDelegateBridge(void)
@@ -25,12 +26,15 @@
MTRDeviceControllerDelegateBridge::~MTRDeviceControllerDelegateBridge(void) {}
-void MTRDeviceControllerDelegateBridge::setDelegate(id<MTRDeviceControllerDelegate> delegate, dispatch_queue_t queue)
+void MTRDeviceControllerDelegateBridge::setDelegate(
+ MTRDeviceController * controller, id<MTRDeviceControllerDelegate> delegate, dispatch_queue_t queue)
{
if (delegate && queue) {
+ mController = controller;
mDelegate = delegate;
mQueue = queue;
} else {
+ mController = nil;
mDelegate = nil;
mQueue = nil;
}
@@ -58,11 +62,12 @@
NSLog(@"DeviceControllerDelegate status updated: %d", status);
id<MTRDeviceControllerDelegate> strongDelegate = mDelegate;
- if ([strongDelegate respondsToSelector:@selector(onStatusUpdate:)]) {
- if (strongDelegate && mQueue) {
+ MTRDeviceController * strongController = mController;
+ if (strongDelegate && mQueue && strongController) {
+ if ([strongDelegate respondsToSelector:@selector(controller:statusUpdate:)]) {
MTRCommissioningStatus commissioningStatus = MapStatus(status);
dispatch_async(mQueue, ^{
- [strongDelegate onStatusUpdate:commissioningStatus];
+ [strongDelegate controller:strongController statusUpdate:commissioningStatus];
});
}
}
@@ -73,11 +78,12 @@
NSLog(@"DeviceControllerDelegate Pairing complete. Status %s", chip::ErrorStr(error));
id<MTRDeviceControllerDelegate> strongDelegate = mDelegate;
- if ([strongDelegate respondsToSelector:@selector(onCommissioningSessionEstablishmentDone:)]) {
- if (strongDelegate && mQueue) {
+ MTRDeviceController * strongController = mController;
+ if (strongDelegate && mQueue && strongController) {
+ if ([strongDelegate respondsToSelector:@selector(controller:commissioningSessionEstablishmentDone:)]) {
dispatch_async(mQueue, ^{
NSError * nsError = [MTRError errorForCHIPErrorCode:error];
- [strongDelegate onCommissioningSessionEstablishmentDone:nsError];
+ [strongDelegate controller:strongController commissioningSessionEstablishmentDone:nsError];
});
}
}
@@ -95,11 +101,12 @@
NSLog(@"DeviceControllerDelegate Commissioning complete. NodeId %llu Status %s", nodeId, chip::ErrorStr(error));
id<MTRDeviceControllerDelegate> strongDelegate = mDelegate;
- if ([strongDelegate respondsToSelector:@selector(onCommissioningComplete:)]) {
- if (strongDelegate && mQueue) {
+ MTRDeviceController * strongController = mController;
+ if (strongDelegate && mQueue && strongController) {
+ if ([strongDelegate respondsToSelector:@selector(controller:commissioningComplete:)]) {
dispatch_async(mQueue, ^{
NSError * nsError = [MTRError errorForCHIPErrorCode:error];
- [strongDelegate onCommissioningComplete:nsError];
+ [strongDelegate controller:strongController commissioningComplete:nsError];
});
}
}
diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
index db8e105..1b5e64d 100644
--- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
+++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
@@ -94,7 +94,7 @@
return self;
}
-- (void)onCommissioningSessionEstablishmentDone:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError *)error
{
XCTAssertEqual(error.code, 0);
@@ -104,10 +104,10 @@
error:&commissionError];
XCTAssertNil(commissionError);
- // Keep waiting for onCommissioningComplete
+ // Keep waiting for controller:MTRXPCListenerSampleTests.mcommissioningComplete
}
-- (void)onCommissioningComplete:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError *)error
{
XCTAssertEqual(error.code, 0);
[_expectation fulfill];
diff --git a/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m b/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m
index ab63959..3d476be 100644
--- a/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m
+++ b/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m
@@ -419,7 +419,7 @@
return self;
}
-- (void)onCommissioningSessionEstablishmentDone:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningSessionEstablishmentDone:(NSError *)error
{
XCTAssertEqual(error.code, 0);
NSError * commissionError = nil;
@@ -428,10 +428,10 @@
error:&commissionError];
XCTAssertNil(commissionError);
- // Keep waiting for onCommissioningComplete
+ // Keep waiting for controller:commissioningComplete
}
-- (void)onCommissioningComplete:(NSError *)error
+- (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSError *)error
{
XCTAssertEqual(error.code, 0);
[_expectation fulfill];