Skip to content

Commit 5d8985b

Browse files
[CodeDriven] Convert Actions cluster to be code-driven (#43471)
* Move Actions cluster to be code driven * Linter error fix * Fix includes and dependencies * Refactor ActionsCluster Get rid of unnecessary checks Move private functions to be helper functions Cleanup code * Read SetURL from ember * Add docs, fix test build * Restyled by clang-format * Actions cluster: address code review feedback - Rename OnStateChanged/OnActionFailed to GenerateEvent overloads taking the event struct directly, reducing parameter count and matching the underlying eventsGenerator API. - Wrap ActionsCluster.cpp in namespace chip::app::Clusters to reduce using-namespace boilerplate. - Replace DispatchActionCommand template with inline decode/validate/ dispatch logic in InvokeCommand, as the template generalization added complexity without benefit. - Move BuildOptionalAttributes and BuildSetupURL (renamed ReadSetupURL) to anonymous-namespace free functions in CodegenIntegration.cpp; replace the fixed-size char[] buffer with std::string. - Add singleton guard (sInstanceCount) to ActionsServer: the Actions cluster is Node-scoped per the Matter spec and must live on a single aggregator endpoint. Log an error on double-instantiation. - Guard ActionListModified/EndpointListModified against calls for a mismatched endpoint. - Make Init/Shutdown idempotent via mRegistered flag to prevent spurious error logs when the destructor calls Shutdown after an explicit call. - Add README.md documenting the Node-scope constraint, per-endpoint * Revisit the comments of the cluster, separate the backward compatability tests * Enable and fix backwards-compatibility tests * Move the backward compatability tests to the same definintion --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent cc7eb2f commit 5d8985b

23 files changed

Lines changed: 1033 additions & 720 deletions

scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/CodeDrivenCallback.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ void MatterAccessControlClusterInitCallback(chip::EndpointId endpointId);
4444

4545
void MatterAccessControlClusterShutdownCallback(chip::EndpointId endpointId, MatterClusterShutdownType shutdownType);
4646

47+
void MatterActionsClusterInitCallback(chip::EndpointId endpointId);
48+
49+
void MatterActionsClusterShutdownCallback(chip::EndpointId endpointId, MatterClusterShutdownType shutdownType);
50+
4751
void MatterBasicInformationClusterInitCallback(chip::EndpointId endpointId);
4852

4953
void MatterBasicInformationClusterShutdownCallback(chip::EndpointId endpointId, MatterClusterShutdownType shutdownType);

scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/CodeDrivenInitShutdown.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ void MatterClusterServerInitCallback(EndpointId endpoint, ClusterId clusterId)
4343
case app::Clusters::AccessControl::Id:
4444
MatterAccessControlClusterInitCallback(endpoint);
4545
break;
46+
case app::Clusters::Actions::Id:
47+
MatterActionsClusterInitCallback(endpoint);
48+
break;
4649
case app::Clusters::BasicInformation::Id:
4750
MatterBasicInformationClusterInitCallback(endpoint);
4851
break;
@@ -173,6 +176,9 @@ void MatterClusterServerShutdownCallback(EndpointId endpoint, ClusterId clusterI
173176
case app::Clusters::AccessControl::Id:
174177
MatterAccessControlClusterShutdownCallback(endpoint, shutdownType);
175178
break;
179+
case app::Clusters::Actions::Id:
180+
MatterActionsClusterShutdownCallback(endpoint, shutdownType);
181+
break;
176182
case app::Clusters::BasicInformation::Id:
177183
MatterBasicInformationClusterShutdownCallback(endpoint, shutdownType);
178184
break;

src/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ if (chip_build_tests) {
5757
"${chip_root}/src/app/clusters/administrator-commissioning-server/tests",
5858
"${chip_root}/src/app/clusters/air-quality-server/tests",
5959
"${chip_root}/src/app/clusters/basic-information/tests",
60+
"${chip_root}/src/app/clusters/actions-server/tests",
6061
"${chip_root}/src/app/clusters/bindings/tests",
6162
"${chip_root}/src/app/clusters/boolean-state-configuration-server/tests",
6263
"${chip_root}/src/app/clusters/boolean-state-server/tests",
@@ -153,6 +154,7 @@ if (chip_build_tests) {
153154
if (chip_device_platform == "darwin" || chip_device_platform == "linux") {
154155
tests += [
155156
# keep-sorted: start
157+
"${chip_root}/src/app/clusters/actions-server/tests:tests-backwards-compatibility",
156158
"${chip_root}/src/app/clusters/chime-server/tests:tests-backwards-compatibility",
157159
"${chip_root}/src/app/clusters/device-energy-management-server/tests:tests-backwards-compatibility",
158160
"${chip_root}/src/app/clusters/electrical-energy-measurement-server/tests:tests-backwards-compatibility",

src/app/clusters/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ source_set("clusters") {
1818
public_deps = [
1919
# keep-sorted: start
2020
"access-control-server",
21+
"actions-server",
2122
"administrator-commissioning-server",
2223
"air-quality-server",
2324
"basic-information",

src/app/clusters/actions-server/ActionsCluster.cpp

Lines changed: 166 additions & 239 deletions
Large diffs are not rendered by default.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
*
3+
* Copyright (c) 2026 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include <app/CommandHandler.h>
21+
#include <app/ConcreteCommandPath.h>
22+
#include <app/clusters/actions-server/ActionsDelegate.h>
23+
#include <app/server-cluster/DefaultServerCluster.h>
24+
#include <app/server-cluster/OptionalAttributeSet.h>
25+
#include <clusters/Actions/Attributes.h>
26+
#include <clusters/Actions/Events.h>
27+
28+
namespace chip::app::Clusters {
29+
30+
class ActionsCluster : public DefaultServerCluster
31+
{
32+
public:
33+
using OptionalAttributesSet = OptionalAttributeSet<Actions::Attributes::SetupURL::Id>;
34+
35+
ActionsCluster(EndpointId endpointId, Actions::Delegate & delegate, OptionalAttributesSet optionalAttributes = {},
36+
std::optional<CharSpan> setupURL = std::nullopt) :
37+
DefaultServerCluster({ endpointId, Actions::Id }),
38+
mDelegate(delegate), mOptionalAttributes(optionalAttributes), mSetupURL(setupURL)
39+
{}
40+
41+
~ActionsCluster() = default;
42+
43+
void ActionListModified();
44+
45+
void EndpointListsModified();
46+
47+
/**
48+
* Public helper API for the Application/Delegate to call asynchronously to emit a Matter event to the fabric.
49+
* Use these when an action's state changes or an action fails.
50+
*/
51+
void GenerateEvent(const Actions::Events::StateChanged::Type & event);
52+
void GenerateEvent(const Actions::Events::ActionFailed::Type & event);
53+
54+
DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request,
55+
AttributeValueEncoder & encoder) override;
56+
57+
std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
58+
chip::TLV::TLVReader & input_arguments,
59+
CommandHandler * handler) override;
60+
61+
CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
62+
63+
CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
64+
ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override;
65+
66+
private:
67+
Actions::Delegate & mDelegate;
68+
const OptionalAttributesSet mOptionalAttributes;
69+
const std::optional<CharSpan> mSetupURL;
70+
71+
CHIP_ERROR ReadActionListAttribute(const DataModel::ReadAttributeRequest & request,
72+
const AttributeValueEncoder::ListEncodeHelper & aEncoder);
73+
74+
CHIP_ERROR ReadEndpointListAttribute(const DataModel::ReadAttributeRequest & request,
75+
const AttributeValueEncoder::ListEncodeHelper & aEncoder);
76+
77+
Protocols::InteractionModel::Status ValidateActionExists(uint16_t actionID, uint16_t & outActionIndex);
78+
79+
Protocols::InteractionModel::Status ValidateCommandSupported(uint16_t actionIndex, CommandId commandId);
80+
};
81+
82+
} // namespace chip::app::Clusters

src/app/clusters/actions-server/ActionsDelegate.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616
*/
1717

1818
#pragma once
19-
20-
#include <app-common/zap-generated/cluster-objects.h>
19+
#include <app/clusters/actions-server/ActionsStructs.h>
20+
#include <clusters/Actions/Commands.h>
2121
#include <lib/core/CHIPError.h>
2222
#include <lib/support/Span.h>
2323

24-
#include "ActionsStructs.h"
25-
2624
namespace chip {
2725
namespace app {
2826
namespace Clusters {

src/app/clusters/actions-server/ActionsStructs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#pragma once
1919

20-
#include <app-common/zap-generated/cluster-objects.h>
20+
#include <clusters/Actions/Structs.h>
2121
#include <lib/support/CodeUtils.h>
2222

2323
namespace chip {

src/app/clusters/actions-server/BUILD.gn

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,20 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
group("actions-server") {
14+
import("//build_overrides/build.gni")
15+
import("//build_overrides/chip.gni")
16+
17+
static_library("actions-server") {
18+
sources = [
19+
"ActionsCluster.cpp",
20+
"ActionsCluster.h",
21+
"ActionsDelegate.h",
22+
"ActionsStructs.h",
23+
]
24+
25+
public_deps = [
26+
"${chip_root}/src/app/server-cluster",
27+
"${chip_root}/src/lib/core",
28+
"${chip_root}/src/lib/support",
29+
]
1530
}

0 commit comments

Comments
 (0)