Skip to content

Commit

Permalink
Use iterator to read supported calendar types (#17037)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufengwangca authored and pull[bot] committed Apr 11, 2022
1 parent d060aed commit 1154860
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <app/util/attribute-storage.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/DeviceInfoProvider.h>
#include <platform/PlatformManager.h>

using namespace chip;
Expand Down Expand Up @@ -57,18 +58,32 @@ TimeFormatLocalizationAttrAccess gAttrAccess;
CHIP_ERROR TimeFormatLocalizationAttrAccess::ReadSupportedCalendarTypes(AttributeValueEncoder & aEncoder)
{
CHIP_ERROR err = CHIP_NO_ERROR;
DeviceLayer::AttributeList<CalendarType, DeviceLayer::kMaxCalendarTypes> supportedCalendarTypes;

if (DeviceLayer::PlatformMgr().GetSupportedCalendarTypes(supportedCalendarTypes) == CHIP_NO_ERROR)
DeviceLayer::DeviceInfoProvider * provider = DeviceLayer::GetDeviceInfoProvider();

if (provider)
{
err = aEncoder.EncodeList([&supportedCalendarTypes](const auto & encoder) -> CHIP_ERROR {
for (auto type : supportedCalendarTypes)
{
ReturnErrorOnFailure(encoder.Encode(type));
}
DeviceLayer::DeviceInfoProvider::SupportedCalendarTypesIterator * it = provider->IterateSupportedCalendarTypes();

if (it)
{
err = aEncoder.EncodeList([&it](const auto & encoder) -> CHIP_ERROR {
CalendarType type;

return CHIP_NO_ERROR;
});
while (it->Next(type))
{
ReturnErrorOnFailure(encoder.Encode(type));
}

return CHIP_NO_ERROR;
});

it->Release();
}
else
{
err = aEncoder.EncodeEmptyList();
}
}
else
{
Expand Down Expand Up @@ -96,25 +111,33 @@ CHIP_ERROR TimeFormatLocalizationAttrAccess::Read(const ConcreteReadAttributePat
// if there are any, and to kBuddhist if there are not.
bool IsSupportedCalendarType(CalendarType newType, CalendarType & validType)
{
DeviceLayer::AttributeList<CalendarType, DeviceLayer::kMaxCalendarTypes> supportedCalendarTypes;
// Reset valid type if no supported calendar types found.
validType = CalendarType::kBuddhist;

DeviceLayer::DeviceInfoProvider * provider = DeviceLayer::GetDeviceInfoProvider();

if (DeviceLayer::PlatformMgr().GetSupportedCalendarTypes(supportedCalendarTypes) == CHIP_NO_ERROR)
if (provider)
{
for (auto type : supportedCalendarTypes)
DeviceLayer::DeviceInfoProvider::SupportedCalendarTypesIterator * it = provider->IterateSupportedCalendarTypes();

if (it)
{
validType = type;
CalendarType type;

if (validType == newType)
while (it->Next(type))
{
return true;
validType = type;

if (validType == newType)
{
it->Release();
return true;
}
}

it->Release();
}
}
else
{
// Reset valid type if no supported calendar types found.
validType = CalendarType::kBuddhist;
}

return false;
}
Expand Down
16 changes: 13 additions & 3 deletions src/include/platform/DeviceInfoProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ class DeviceInfoProvider

using FixedLabelType = app::Clusters::FixedLabel::Structs::LabelStruct::Type;
using UserLabelType = app::Clusters::UserLabel::Structs::LabelStruct::Type;
using CalendarType = app::Clusters::TimeFormatLocalization::CalendarType;

using FixedLabelIterator = Iterator<FixedLabelType>;
using UserLabelIterator = Iterator<UserLabelType>;
using SupportedLocalesIterator = Iterator<CharSpan>;
using FixedLabelIterator = Iterator<FixedLabelType>;
using UserLabelIterator = Iterator<UserLabelType>;
using SupportedLocalesIterator = Iterator<CharSpan>;
using SupportedCalendarTypesIterator = Iterator<CalendarType>;

DeviceInfoProvider() = default;

Expand Down Expand Up @@ -101,6 +103,14 @@ class DeviceInfoProvider
*/
virtual SupportedLocalesIterator * IterateSupportedLocales() = 0;

/**
* Creates an iterator that may be used to obtain the list of supported calendar types of the device.
* In order to release the allocated memory, the Release() method must be called after the iteration is finished.
* @retval An instance of EndpointIterator on success
* @retval nullptr if no iterator instances are available.
*/
virtual SupportedCalendarTypesIterator * IterateSupportedCalendarTypes() = 0;

protected:
/**
* @brief Set the UserLabel at the specified index of the UserLabelList on a given endpoint
Expand Down
9 changes: 0 additions & 9 deletions src/include/platform/PlatformManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,6 @@ class PlatformManager
bool IsChipStackLockedByCurrentThread() const;
#endif

CHIP_ERROR GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes);

/*
* PostEvent can be called safely on any thread without locking the stack.
* When called from a thread that is not doing the stack work item
Expand Down Expand Up @@ -447,11 +444,5 @@ inline CHIP_ERROR PlatformManager::StartChipTimer(System::Clock::Timeout duratio
return static_cast<ImplClass *>(this)->_StartChipTimer(duration);
}

inline CHIP_ERROR PlatformManager::GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes)
{
return static_cast<ImplClass *>(this)->_GetSupportedCalendarTypes(supportedCalendarTypes);
}

} // namespace DeviceLayer
} // namespace chip
10 changes: 0 additions & 10 deletions src/include/platform/internal/GenericPlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class GenericPlatformManagerImpl
void _ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg);
void _DispatchEvent(const ChipDeviceEvent * event);

CHIP_ERROR _GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes);

// ===== Support methods that can be overridden by the implementation subclass.

void DispatchEventToDeviceLayer(const ChipDeviceEvent * event);
Expand All @@ -78,13 +75,6 @@ class GenericPlatformManagerImpl
// Instruct the compiler to instantiate the template only when explicitly told to do so.
extern template class GenericPlatformManagerImpl<PlatformManagerImpl>;

template <class ImplClass>
inline CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes)
{
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
21 changes: 0 additions & 21 deletions src/platform/Darwin/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,26 +136,5 @@ CHIP_ERROR PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * event)
return CHIP_NO_ERROR;
}

CHIP_ERROR
PlatformManagerImpl::_GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes)
{
// In Darwin simulation, return following supported Calendar Types
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kBuddhist);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kChinese);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kCoptic);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kEthiopian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kGregorian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kHebrew);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kIndian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kIslamic);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kJapanese);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kKorean);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kPersian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kTaiwanese);

return CHIP_NO_ERROR;
}

} // namespace DeviceLayer
} // namespace chip
3 changes: 0 additions & 3 deletions src/platform/Darwin/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener
CHIP_ERROR _StartEventLoopTask();
CHIP_ERROR _StopEventLoopTask();

CHIP_ERROR _GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes);

void _RunEventLoop();
void _LockChipStack(){};
bool _TryLockChipStack() { return false; };
Expand Down
75 changes: 75 additions & 0 deletions src/platform/Linux/DeviceInfoProviderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,5 +267,80 @@ bool DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Next(CharSpan & outpu
}
}

DeviceInfoProvider::SupportedCalendarTypesIterator * DeviceInfoProviderImpl::IterateSupportedCalendarTypes()
{
return new SupportedCalendarTypesIteratorImpl();
}

size_t DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Count()
{
// In Linux Simulation, return the size of the hardcoded list of Strings that are valid values for the Calendar Types.
// {("kBuddhist"), ("kChinese"), ("kCoptic"), ("kEthiopian"), ("kGregorian"), ("kHebrew"), ("kIndian"), ("kJapanese"),
// ("kKorean"), ("kPersian"), ("kTaiwanese"), ("kIslamic")}

return 12;
}

bool DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output)
{
// In Linux Simulation, return following hardcoded list of Strings that are valid values for the Calendar Types.
CHIP_ERROR err = CHIP_NO_ERROR;

VerifyOrReturnError(mIndex < 12, false);

switch (mIndex)
{
case 0:
output = app::Clusters::TimeFormatLocalization::CalendarType::kBuddhist;
break;
case 1:
output = app::Clusters::TimeFormatLocalization::CalendarType::kChinese;
break;
case 2:
output = app::Clusters::TimeFormatLocalization::CalendarType::kCoptic;
break;
case 3:
output = app::Clusters::TimeFormatLocalization::CalendarType::kEthiopian;
break;
case 4:
output = app::Clusters::TimeFormatLocalization::CalendarType::kGregorian;
break;
case 5:
output = app::Clusters::TimeFormatLocalization::CalendarType::kHebrew;
break;
case 6:
output = app::Clusters::TimeFormatLocalization::CalendarType::kIndian;
break;
case 7:
output = app::Clusters::TimeFormatLocalization::CalendarType::kJapanese;
break;
case 8:
output = app::Clusters::TimeFormatLocalization::CalendarType::kKorean;
break;
case 9:
output = app::Clusters::TimeFormatLocalization::CalendarType::kPersian;
break;
case 10:
output = app::Clusters::TimeFormatLocalization::CalendarType::kTaiwanese;
break;
case 11:
output = app::Clusters::TimeFormatLocalization::CalendarType::kIslamic;
break;
default:
err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
break;
}

if (err == CHIP_NO_ERROR)
{
mIndex++;
return true;
}
else
{
return false;
}
}

} // namespace DeviceLayer
} // namespace chip
13 changes: 13 additions & 0 deletions src/platform/Linux/DeviceInfoProviderImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DeviceInfoProviderImpl : public DeviceInfoProvider
FixedLabelIterator * IterateFixedLabel(EndpointId endpoint) override;
UserLabelIterator * IterateUserLabel(EndpointId endpoint) override;
SupportedLocalesIterator * IterateSupportedLocales() override;
SupportedCalendarTypesIterator * IterateSupportedCalendarTypes() override;

static DeviceInfoProviderImpl & GetDefaultInstance();

Expand Down Expand Up @@ -80,6 +81,18 @@ class DeviceInfoProviderImpl : public DeviceInfoProvider
char mActiveLocaleBuf[kMaxActiveLocaleLength + 1];
};

class SupportedCalendarTypesIteratorImpl : public SupportedCalendarTypesIterator
{
public:
SupportedCalendarTypesIteratorImpl() = default;
size_t Count() override;
bool Next(CalendarType & output) override;
void Release() override { delete this; }

private:
size_t mIndex = 0;
};

CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) override;
CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) override;
CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) override;
Expand Down
21 changes: 0 additions & 21 deletions src/platform/Linux/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,27 +242,6 @@ CHIP_ERROR PlatformManagerImpl::_Shutdown()
return Internal::GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>::_Shutdown();
}

CHIP_ERROR
PlatformManagerImpl::_GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes)
{
// In Linux simulation, return following supported Calendar Types
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kBuddhist);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kChinese);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kCoptic);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kEthiopian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kGregorian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kHebrew);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kIndian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kIslamic);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kJapanese);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kKorean);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kPersian);
supportedCalendarTypes.add(app::Clusters::TimeFormatLocalization::CalendarType::kTaiwanese);

return CHIP_NO_ERROR;
}

void PlatformManagerImpl::HandleGeneralFault(uint32_t EventId)
{
GeneralDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();
Expand Down
2 changes: 0 additions & 2 deletions src/platform/Linux/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener

CHIP_ERROR _InitChipStack();
CHIP_ERROR _Shutdown();
CHIP_ERROR _GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes);

// ===== Members for internal use by the following friends.

Expand Down
6 changes: 0 additions & 6 deletions src/platform/fake/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@ class PlatformManagerImpl final : public PlatformManager

CHIP_ERROR _StartChipTimer(System::Clock::Timeout duration) { return CHIP_ERROR_NOT_IMPLEMENTED; }

CHIP_ERROR _GetSupportedCalendarTypes(
AttributeList<app::Clusters::TimeFormatLocalization::CalendarType, kMaxCalendarTypes> & supportedCalendarTypes)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

void _LockChipStack() {}
bool _TryLockChipStack() { return true; }
void _UnlockChipStack() {}
Expand Down

0 comments on commit 1154860

Please sign in to comment.