Encode the user label list in place so that we can free the label lis… (#16510)

* Encode the user label list in place so that we can free the label list after usage

* Update src/app/clusters/user-label-server/user-label-server.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Refactor userlabellist API to DeviceInfoProvider

* Add API documentation

* Update src/include/platform/DeviceInfoProvider.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/include/platform/DeviceInfoProvider.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Rename SetUserLabelCount/GetUserLabelCount to SetUserLabelLength/GetUserLabelLength

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/src/include/platform/DeviceInfoProvider.h b/src/include/platform/DeviceInfoProvider.h
index 3dfe278..cb23e97 100644
--- a/src/include/platform/DeviceInfoProvider.h
+++ b/src/include/platform/DeviceInfoProvider.h
@@ -28,8 +28,9 @@
 namespace chip {
 namespace DeviceLayer {
 
-static constexpr size_t kMaxLabelNameLength  = 16;
-static constexpr size_t kMaxLabelValueLength = 16;
+static constexpr size_t kMaxUserLabelListLength = 10;
+static constexpr size_t kMaxLabelNameLength     = 16;
+static constexpr size_t kMaxLabelValueLength    = 16;
 
 class DeviceInfoProvider
 {
@@ -63,8 +64,10 @@
     };
 
     using FixedLabelType = app::Clusters::FixedLabel::Structs::LabelStruct::Type;
+    using UserLabelType  = app::Clusters::UserLabel::Structs::LabelStruct::Type;
 
     using FixedLabelIterator = Iterator<FixedLabelType>;
+    using UserLabelIterator  = Iterator<UserLabelType>;
 
     DeviceInfoProvider() = default;
 
@@ -74,15 +77,49 @@
     DeviceInfoProvider(const DeviceInfoProvider &) = delete;
     DeviceInfoProvider & operator=(const DeviceInfoProvider &) = delete;
 
+    CHIP_ERROR SetUserLabelList(EndpointId endpoint, const AttributeList<UserLabelType, kMaxUserLabelListLength> & labelList);
+    CHIP_ERROR AppendUserLabel(EndpointId endpoint, const UserLabelType & label);
+
     // Iterators
     /**
-     *  Creates an iterator that may be used to obtain the list of user labels associated with the given endpoint.
+     *  Creates an iterator that may be used to obtain the list of labels associated with the given endpoint.
      *  In order to release the allocated memory, the Release() method must be called after the iteration is finished.
-     *  Modifying the user label during the iteration is currently not supported, and may yield unexpected behaviour.
+     *  Modifying the label during the iteration is currently not supported, and may yield unexpected behaviour.
      *  @retval An instance of EndpointIterator on success
      *  @retval nullptr if no iterator instances are available.
      */
     virtual FixedLabelIterator * IterateFixedLabel(EndpointId endpoint) = 0;
+    virtual UserLabelIterator * IterateUserLabel(EndpointId endpoint)   = 0;
+
+protected:
+    /**
+     * @brief Set the UserLabel at the specified index of the UserLabelList on a given endpoint
+     *
+     * @param endpoint - id to UserLabelList on which to set the UserLabel.
+     * @param index - index within the UserLabelList for which to set the UserLabel.
+     * @param userLabel - user label to set.
+     * @return CHIP_NO_ERROR on success, CHIP_ERROR_INVALID_KEY_ID if index exceed the range (Total length - 1),
+     *         or other CHIP_ERROR values from implementation on other errors.
+     */
+    virtual CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) = 0;
+
+    /**
+     * @brief Set the total length of the UserLabelList on a given endpoint
+     *
+     * @param endpoint - id of the UserLabelList.
+     * @param val - total count of the UserLabelList.
+     * @return CHIP_NO_ERROR on success, other CHIP_ERROR values from implementation on other errors.
+     */
+    virtual CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) = 0;
+
+    /**
+     * @brief Get the total length of the UserLabelList on a given endpoint
+     *
+     * @param endpoint - id of the UserLabelList.
+     * @param val - output of the total count of the UserLabelList.
+     * @return CHIP_NO_ERROR on success, other CHIP_ERROR values from implementation on other errors.
+     */
+    virtual CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) = 0;
 };
 
 /**