Skip to content

Commit 600564c

Browse files
nivi-applerestyled-commitsbzbarsky-apple
authored
Add support for notifying the delegate when device configuration changes (project-chip#33146)
* Add support for notifying the delegate when device configuration changes - Device configuration changes include updates in attributes parts list, server list, device type list, cluster revision or feature map in the descriptor cluster - Add a test to verify the delegate is notified when device configuration changes * Restyled by clang-format * Change device list to device type list * Add accepted commands list and attribute list to the list of attributes that qualify as device configuration changes * Set _deviceConfigurationChanged to NO in _handleReportEnd * Update src/darwin/Framework/CHIP/MTRDevice.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Addressed review comments * Restyled by clang-format * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update code to set _deviceConfigurationChanged correctly in _getAttributesToReportWithReportedValues - Add more tests to verify that for attributes that don't affect device configuration changed, the delegate callback is not called. Also add tests for testing an attribute report having multiple attributes one of which causes device configuration changed. * Restyled by clang-format * Add logs to test the multiple attribute report * Fix the checkAttributeReportTriggersConfigurationChanged API and invert the expectation for device configuration changed when expectConfigurationChanged is set to NO * Restyled by clang-format * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Addressed comments --------- Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent e6d3184 commit 600564c

File tree

6 files changed

+517
-0
lines changed

6 files changed

+517
-0
lines changed

src/darwin/Framework/CHIP/MTRDevice.h

+8
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,14 @@ MTR_EXTERN NSString * const MTRDataVersionKey MTR_NEWLY_AVAILABLE;
423423
*/
424424
- (void)deviceCachePrimed:(MTRDevice *)device MTR_NEWLY_AVAILABLE;
425425

426+
/**
427+
* This is called when the MTRDevice object detects a change in the device configuration.
428+
*
429+
* Device configuration is the set of functionality implemented by the device.
430+
*
431+
*/
432+
- (void)deviceConfigurationChanged:(MTRDevice *)device MTR_NEWLY_AVAILABLE;
433+
426434
@end
427435

428436
@interface MTRDevice (Deprecated)

src/darwin/Framework/CHIP/MTRDevice.mm

+56
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ @implementation MTRDevice {
378378
// ReadClient). Nil if we have had no such failures.
379379
NSDate * _Nullable _lastSubscriptionFailureTime;
380380
MTRDeviceConnectivityMonitor * _connectivityMonitor;
381+
382+
// This boolean keeps track of any device configuration changes received in an attribute report.
383+
// If this is true when the report ends, we notify the delegate.
384+
BOOL _deviceConfigurationChanged;
381385
}
382386

383387
- (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceController *)controller
@@ -1090,6 +1094,19 @@ - (void)_handleReportEnd
10901094
_clusterDataToPersist = nil;
10911095
}
10921096

1097+
// After the handling of the report, if we detected a device configuration change, notify the delegate
1098+
// of the same.
1099+
if (_deviceConfigurationChanged) {
1100+
id<MTRDeviceDelegate> delegate = _weakDelegate.strongObject;
1101+
if (delegate) {
1102+
dispatch_async(_delegateQueue, ^{
1103+
if ([delegate respondsToSelector:@selector(deviceConfigurationChanged:)])
1104+
[delegate deviceConfigurationChanged:self];
1105+
});
1106+
}
1107+
_deviceConfigurationChanged = NO;
1108+
}
1109+
10931110
// For unit testing only
10941111
#ifdef DEBUG
10951112
id delegate = _weakDelegate.strongObject;
@@ -1132,6 +1149,15 @@ - (void)unitTestInjectEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eve
11321149
[self _handleEventReport:eventReport];
11331150
});
11341151
}
1152+
1153+
- (void)unitTestInjectAttributeReport:(NSArray<NSDictionary<NSString *, id> *> *)attributeReport
1154+
{
1155+
dispatch_async(self.queue, ^{
1156+
[self _handleReportBegin];
1157+
[self _handleAttributeReport:attributeReport];
1158+
[self _handleReportEnd];
1159+
});
1160+
}
11351161
#endif
11361162

11371163
- (void)_handleEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventReport
@@ -2443,6 +2469,30 @@ - (void)_noteDataVersion:(NSNumber *)dataVersion forClusterPath:(MTRClusterPath
24432469
}
24442470
}
24452471

2472+
- (BOOL)_attributeAffectsDeviceConfiguration:(MTRAttributePath *)attributePath
2473+
{
2474+
// Check for attributes in the descriptor cluster that affect device configuration.
2475+
if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID) {
2476+
switch (attributePath.attribute.unsignedLongValue) {
2477+
case MTRAttributeIDTypeClusterDescriptorAttributePartsListID:
2478+
case MTRAttributeIDTypeClusterDescriptorAttributeServerListID:
2479+
case MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID: {
2480+
return YES;
2481+
}
2482+
}
2483+
}
2484+
2485+
// Check for global attributes that affect device configuration.
2486+
switch (attributePath.attribute.unsignedLongValue) {
2487+
case MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID:
2488+
case MTRAttributeIDTypeGlobalAttributeAttributeListID:
2489+
case MTRAttributeIDTypeGlobalAttributeClusterRevisionID:
2490+
case MTRAttributeIDTypeGlobalAttributeFeatureMapID:
2491+
return YES;
2492+
}
2493+
return NO;
2494+
}
2495+
24462496
// assume lock is held
24472497
- (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSString *, id> *> *)reportedAttributeValues
24482498
{
@@ -2495,6 +2545,12 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
24952545
// Now that we have grabbed previousValue, update our cache with the attribute value.
24962546
if (readCacheValueChanged) {
24972547
[self _setCachedAttributeValue:attributeDataValue forPath:attributePath];
2548+
if (!_deviceConfigurationChanged) {
2549+
_deviceConfigurationChanged = [self _attributeAffectsDeviceConfiguration:attributePath];
2550+
if (_deviceConfigurationChanged) {
2551+
MTR_LOG_INFO("Device configuration changed due to changes in attribute %@", attributePath);
2552+
}
2553+
}
24982554
}
24992555

25002556
#ifdef DEBUG

0 commit comments

Comments
 (0)