@@ -336,6 +336,7 @@ - (void)unitTestReportEndForDevice:(MTRDevice *)device;
336
336
- (BOOL )unitTestShouldSetUpSubscriptionForDevice : (MTRDevice *)device ;
337
337
- (BOOL )unitTestShouldSkipExpectedValuesForWrite : (MTRDevice *)device ;
338
338
- (NSNumber *)unitTestMaxIntervalOverrideForSubscription : (MTRDevice *)device ;
339
+ - (BOOL )unitTestForceAttributeReportsIfMatchingCache : (MTRDevice *)device ;
339
340
@end
340
341
#endif
341
342
@@ -745,7 +746,7 @@ - (BOOL)_subscriptionAbleToReport
745
746
746
747
// Unfortunately, we currently have no subscriptions over our hacked-up XPC
747
748
// setup. Try to detect that situation.
748
- if ([_deviceController.class respondsToSelector: @selector ( sharedControllerWithID:xpcConnectBlock: ) ]) {
749
+ if ([_deviceController isKindOfClass: MTRDeviceControllerOverXPC. class ]) {
749
750
return NO ;
750
751
}
751
752
@@ -1603,24 +1604,33 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath)
1603
1604
- (NSDictionary <NSString *, id> * _Nullable)readAttributeWithEndpointID : (NSNumber *)endpointID
1604
1605
clusterID : (NSNumber *)clusterID
1605
1606
attributeID : (NSNumber *)attributeID
1606
- params : (MTRReadParams *)params
1607
+ params : (MTRReadParams * _Nullable )params
1607
1608
{
1608
1609
MTRAttributePath * attributePath = [MTRAttributePath attributePathWithEndpointID: endpointID
1609
1610
clusterID: clusterID
1610
1611
attributeID: attributeID];
1611
1612
1612
1613
BOOL attributeIsSpecified = MTRAttributeIsSpecified (clusterID.unsignedIntValue , attributeID.unsignedIntValue );
1613
- BOOL hasChangesOmittedQuality = AttributeHasChangesOmittedQuality (attributePath);
1614
+ BOOL hasChangesOmittedQuality;
1615
+ if (attributeIsSpecified) {
1616
+ hasChangesOmittedQuality = AttributeHasChangesOmittedQuality (attributePath);
1617
+ } else {
1618
+ if (params == nil ) {
1619
+ hasChangesOmittedQuality = NO ;
1620
+ } else {
1621
+ hasChangesOmittedQuality = !params.assumeUnknownAttributesReportable ;
1622
+ }
1623
+ }
1614
1624
1615
1625
// Return current known / expected value right away
1616
1626
NSDictionary <NSString *, id > * attributeValueToReturn = [self _attributeValueDictionaryForAttributePath: attributePath];
1617
1627
1618
1628
// Send read request to device if any of the following are true:
1619
- // 1. The attribute is not in the specification (so we don't know whether hasChangesOmittedQuality can be trusted).
1620
- // 2. Subscription not in a state we can expect reports
1621
- // 3. There is subscription but attribute has Changes Omitted quality
1622
- // TODO: add option for BaseSubscriptionCallback to report during priming, to reduce when case 4 is hit
1623
- if (!attributeIsSpecified || ! [self _subscriptionAbleToReport ] || hasChangesOmittedQuality) {
1629
+ // 1. Subscription not in a state we can expect reports
1630
+ // 2. The attribute has the Changes Omitted quality, so we won't get reports for it.
1631
+ // 3. The attribute is not in the spec, and the read params asks to assume
1632
+ // an unknown attribute has the Changes Omitted quality.
1633
+ if (![self _subscriptionAbleToReport ] || hasChangesOmittedQuality) {
1624
1634
// Read requests container will be a mutable array of items, each being an array containing:
1625
1635
// [attribute request path, params]
1626
1636
// Batching handler should only coalesce when params are equal.
@@ -2344,6 +2354,18 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
2344
2354
}
2345
2355
NSArray * expectedValue = _expectedValueCache[attributePath];
2346
2356
2357
+ // Unit test only code.
2358
+ #ifdef DEBUG
2359
+ if (!readCacheValueChanged) {
2360
+ id delegate = _weakDelegate.strongObject ;
2361
+ if (delegate) {
2362
+ if ([delegate respondsToSelector: @selector (unitTestForceAttributeReportsIfMatchingCache: )]) {
2363
+ readCacheValueChanged = [delegate unitTestForceAttributeReportsIfMatchingCache: self ];
2364
+ }
2365
+ }
2366
+ }
2367
+ #endif // DEBUG
2368
+
2347
2369
// Report the attribute if a read would get a changed value. This happens
2348
2370
// when our cached value changes and no expected value exists.
2349
2371
if (readCacheValueChanged && !expectedValue) {
0 commit comments