erpt: implement AppletActiveTimeInfoList

This commit is contained in:
Michael Scire 2021-04-16 00:55:22 -07:00
parent 0a6219e6e0
commit 5bb790e4a7
3 changed files with 68 additions and 6 deletions

View file

@ -26,8 +26,8 @@
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0) \
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out<erpt::AttachmentId> out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \

View file

@ -89,6 +89,11 @@ namespace ams::erpt::srv {
Journal::Restore();
if (hos::GetVersion() >= hos::Version_12_0_0) {
Reporter::UpdatePowerOnTime();
Reporter::UpdateAwakeTime();
}
return ResultSuccess();
}

View file

@ -36,6 +36,61 @@ namespace ams::erpt::srv {
constinit os::SdkMutex g_limit_mutex;
constinit bool g_submitted_limit = false;
class AppletActiveTimeInfoList {
private:
struct AppletActiveTimeInfo {
ncm::ProgramId program_id;
os::Tick register_tick;
TimeSpan suspended_duration;
};
static constexpr AppletActiveTimeInfo InvalidAppletActiveTimeInfo = { ncm::InvalidProgramId, os::Tick{}, TimeSpan::FromNanoSeconds(0) };
private:
std::array<AppletActiveTimeInfo, 8> m_list;
public:
constexpr AppletActiveTimeInfoList() : m_list{InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo, InvalidAppletActiveTimeInfo} {
m_list.fill(InvalidAppletActiveTimeInfo);
}
public:
void Register(ncm::ProgramId program_id) {
/* Find an unused entry. */
auto entry = util::range::find_if(m_list, [](const AppletActiveTimeInfo &info) { return info.program_id == ncm::InvalidProgramId; });
AMS_ASSERT(entry != m_list.end());
/* Create the entry. */
*entry = { program_id, os::GetSystemTick(), TimeSpan::FromNanoSeconds(0) };
}
void Unregister(ncm::ProgramId program_id) {
/* Find a matching entry. */
auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
AMS_ASSERT(entry != m_list.end());
/* Clear the entry. */
*entry = InvalidAppletActiveTimeInfo;
}
void UpdateSuspendedDuration(ncm::ProgramId program_id, TimeSpan suspended_duration) {
/* Find a matching entry. */
auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
AMS_ASSERT(entry != m_list.end());
/* Set the suspended duration. */
entry->suspended_duration = suspended_duration;
}
std::optional<TimeSpan> GetActiveDuration(ncm::ProgramId program_id) const {
/* Try to find a matching entry. */
const auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
if (entry != m_list.end()) {
return (os::GetSystemTick() - entry->register_tick).ToTimeSpan() - entry->suspended_duration;
} else {
return std::nullopt;
}
}
};
constinit AppletActiveTimeInfoList g_applet_active_time_info_list;
Result PullErrorContext(size_t *out_total_size, size_t *out_size, void *dst, size_t dst_size, const err::ContextDescriptor &descriptor, Result result) {
s32 unk0;
u32 total_size, size;
@ -258,9 +313,9 @@ namespace ams::erpt::srv {
SubmitErrorContext(record.get(), this->ctx_result);
}
record->Add(FieldId_OsVersion, s_os_version, strnlen(s_os_version, sizeof(s_os_version)));
record->Add(FieldId_PrivateOsVersion, s_private_os_version, strnlen(s_private_os_version, sizeof(s_private_os_version)));
record->Add(FieldId_SerialNumber, s_serial_number, strnlen(s_serial_number, sizeof(s_serial_number)));
record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version)));
record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version)));
record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number)));
record->Add(FieldId_ReportIdentifier, this->identifier_str, sizeof(this->identifier_str));
record->Add(FieldId_OccurrenceTimestamp, this->timestamp_user.value);
record->Add(FieldId_OccurrenceTimestampNet, this->timestamp_network.value);
@ -281,13 +336,15 @@ namespace ams::erpt::srv {
}
if (s_awake_time) {
record->Add(FieldId_ElapsedTimeSincePowerOn, (this->occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds());
record->Add(FieldId_ElapsedTimeSinceLastAwake, (this->occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds());
}
if (s_application_launch_time) {
record->Add(FieldId_ApplicationAliveTime, (this->occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds());
}
/* TODO: Add FieldId_AppletTotalActiveTime. */
R_TRY(Context::SubmitContextRecord(std::move(record)));
R_TRY(Context::SubmitContext(this->ctx, this->data, this->data_size));