Use GlobalAttributesNotInMetadata instead of hardcoding the names. (#22453)

* Use GlobalAttributesNotInMetadata instead of hardcoding the names.

This way when we add EventList things should work right most places
without needing to hunt them down and fix them.

Fixes https://github.com/project-chip/connectedhomeip/issues/22443

* Address review comment.
diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp
index 31390a9..6905527 100644
--- a/src/app/util/ember-compatibility-functions.cpp
+++ b/src/app/util/ember-compatibility-functions.cpp
@@ -415,6 +415,12 @@
         return EncodeCommandList(aPath, aEncoder, &CommandHandlerInterface::EnumerateGeneratedCommands,
                                  mCluster->generatedCommandList);
     default:
+        // This function is only called if attributeCluster is non-null in
+        // ReadSingleClusterData, which only happens for attributes listed in
+        // GlobalAttributesNotInMetadata.  If we reach this code, someone added
+        // a global attribute to that list but not the above switch.
+        VerifyOrDieWithMsg(false, DataManagement, "Unexpected global attribute: " ChipLogFormatMEI,
+                           ChipLogValueMEI(aPath.mAttributeId));
         return CHIP_NO_ERROR;
     }
 }
@@ -551,16 +557,19 @@
     const EmberAfCluster * attributeCluster            = nullptr;
     const EmberAfAttributeMetadata * attributeMetadata = nullptr;
 
-    switch (aPath.mAttributeId)
+    bool isGlobalAttributeNotInMetadata = false;
+    for (auto & attr : GlobalAttributesNotInMetadata)
     {
-    case Clusters::Globals::Attributes::AttributeList::Id:
-        FALLTHROUGH;
-    case Clusters::Globals::Attributes::AcceptedCommandList::Id:
-        FALLTHROUGH;
-    case Clusters::Globals::Attributes::GeneratedCommandList::Id:
-        attributeCluster = emberAfFindCluster(aPath.mEndpointId, aPath.mClusterId, CLUSTER_MASK_SERVER);
-        break;
-    default:
+        if (attr == aPath.mAttributeId)
+        {
+            isGlobalAttributeNotInMetadata = true;
+            attributeCluster               = emberAfFindCluster(aPath.mEndpointId, aPath.mClusterId, CLUSTER_MASK_SERVER);
+            break;
+        }
+    }
+
+    if (!isGlobalAttributeNotInMetadata)
+    {
         attributeMetadata = emberAfLocateAttributeMetadata(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId);
     }
 
diff --git a/src/darwin/Framework/CHIP/MTRIMDispatch.mm b/src/darwin/Framework/CHIP/MTRIMDispatch.mm
index 7979c34..7d0594b 100644
--- a/src/darwin/Framework/CHIP/MTRIMDispatch.mm
+++ b/src/darwin/Framework/CHIP/MTRIMDispatch.mm
@@ -28,6 +28,7 @@
 #include <app/CommandHandler.h>
 #include <app/ConcreteAttributePath.h>
 #include <app/ConcreteCommandPath.h>
+#include <app/GlobalAttributes.h>
 #include <app/MessageDef/AttributeReportIBs.h>
 #include <app/MessageDef/StatusIB.h>
 #include <app/WriteHandler.h>
@@ -66,11 +67,29 @@
 
     namespace {
 
-        Status DetermineAttributeStatus(const ConcreteAttributePath & aPath, bool aIsWrite)
+        bool IsSupportedGlobalAttribute(AttributeId aAttribute)
         {
             // We don't have any non-global attributes.
             using namespace Globals::Attributes;
 
+            for (auto & attr : GlobalAttributesNotInMetadata) {
+                if (attr == aAttribute) {
+                    return true;
+                }
+            }
+
+            switch (aAttribute) {
+            case FeatureMap::Id:
+                FALLTHROUGH;
+            case ClusterRevision::Id:
+                return true;
+            }
+
+            return false;
+        }
+
+        Status DetermineAttributeStatus(const ConcreteAttributePath & aPath, bool aIsWrite)
+        {
             // TODO: Consider making this configurable for applications that are not
             // trying to be an OTA provider, though in practice it just affects which
             // error is returned.
@@ -85,30 +104,13 @@
                 return Status::UnsupportedCluster;
             }
 
-            switch (aPath.mAttributeId) {
-            case AttributeList::Id:
-                FALLTHROUGH;
-            case AcceptedCommandList::Id:
-                FALLTHROUGH;
-            case GeneratedCommandList::Id:
-                FALLTHROUGH;
-                // When EventList is supported, include it here.
-#if 0
-    case EventList::Id:
-        FALLTHROUGH;
-#endif
-            case FeatureMap::Id:
-                FALLTHROUGH;
-            case ClusterRevision::Id:
-                // No permissions for this for read, and none of these are writable for
-                // write.  The writable-or-not check happens before the ACL check.
-                return aIsWrite ? Status::UnsupportedWrite : Status::UnsupportedAccess;
-            default:
-                // No other attributes.
-                break;
+            if (!IsSupportedGlobalAttribute(aPath.mAttributeId)) {
+                return Status::UnsupportedAttribute;
             }
 
-            return Status::UnsupportedAttribute;
+            // No permissions for this for read, and none of these are writable for
+            // write.  The writable-or-not check happens before the ACL check.
+            return aIsWrite ? Status::UnsupportedWrite : Status::UnsupportedAccess;
         }
 
     } // anonymous namespace