From 5d42d920de46da694d69ddc6500faf5834638e72 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky <bzbarsky@apple.com> Date: Mon, 9 Dec 2024 20:03:50 -0500 Subject: [PATCH] Add a helper method to get the descriptor cluster info from MTRDevice. (#36769) --- src/darwin/Framework/CHIP/MTRDevice.h | 9 +++++++ src/darwin/Framework/CHIP/MTRDevice.mm | 26 +++++++++++++++++++ .../Framework/CHIPTests/MTRDeviceTests.m | 16 ++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index b1ca179df658f7..ae355605626ad9 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -221,6 +221,15 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) */ - (NSArray<NSDictionary<NSString *, id> *> *)readAttributePaths:(NSArray<MTRAttributeRequestPath *> *)attributePaths MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)); +/** + * Read all known attributes from descriptor clusters on all known endpoints. + * + * @return A dictionary with the paths of the attributes as keys and the + * data-values (as described in the documentation for + * MTRDeviceResponseHandler) as values. + */ +- (NSDictionary<MTRAttributePath *, NSDictionary<NSString *, id> *> *)descriptorClusters MTR_NEWLY_AVAILABLE; + /** * Invoke a command with a designated command path * diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 7f273e26f03399..4bf71496b0cf1f 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -363,6 +363,32 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID return [NSArray array]; } +- (NSDictionary<MTRAttributePath *, NSDictionary<NSString *, id> *> *)descriptorClusters +{ + @autoreleasepool { + // For now, we have a temp array that we should make sure dies as soon + // as possible. + // + // TODO: We should have a version of readAttributePaths that returns a + // dictionary in the format we want here. + auto path = [MTRAttributeRequestPath requestPathWithEndpointID:nil + clusterID:@(MTRClusterIDTypeDescriptorID) + attributeID:nil]; + auto * data = [self readAttributePaths:@[ path ]]; + + auto * retval = [NSMutableDictionary dictionaryWithCapacity:data.count]; + for (NSDictionary * item in data) { + // We double-check that the things in our dictionaries are the right + // thing, because XPC has no way to check that for us. + if (MTR_SAFE_CAST(item[MTRAttributePathKey], MTRAttributePath) && MTR_SAFE_CAST(item[MTRDataKey], NSDictionary)) { + retval[item[MTRAttributePathKey]] = item[MTRDataKey]; + } + } + + return retval; + } +} + - (void)invokeCommandWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID commandID:(NSNumber *)commandID diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 6cabe01cb567ed..729e7a318a9213 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1588,6 +1588,22 @@ - (void)test017_TestMTRDeviceBasics XCTAssertEqualObjects([NSSet setWithArray:variousThings], [[NSSet setWithArray:clusterRevisions] setByAddingObjectsFromSet:[NSSet setWithArray:basicInformationAllRootAttributes]]); + // Quick test for descriptorClusters + __auto_type * descriptorPath = [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:nil]; + __auto_type * descriptorRead = [device descriptorClusters]; + __auto_type * descriptorWildcardRead = [device readAttributePaths:@[ descriptorPath ]]; + XCTAssertEqual(descriptorRead.count, descriptorWildcardRead.count); + for (MTRAttributePath * path in descriptorRead) { + __auto_type * expectedObj = @{ + MTRAttributePathKey : path, + MTRDataKey : descriptorRead[path], + }; + XCTAssertTrue([descriptorWildcardRead containsObject:expectedObj]); + } + for (NSDictionary * item in descriptorWildcardRead) { + XCTAssertEqualObjects(descriptorRead[item[MTRAttributePathKey]], item[MTRDataKey]); + } + // Some quick tests for waitForAttributeValues. First, values that we know // are already there: XCTestExpectation * deviceTypesWaitExpectation = [self expectationWithDescription:@"deviceTypes is already the value we expect"];