Merge pull request #12845 from liamwhite/notif
notif: rewrite for new IPC
This commit is contained in:
		| @@ -31,8 +31,11 @@ void LoopProcess(Core::System& system) { | ||||
|     // Error Context | ||||
|     server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system)); | ||||
|  | ||||
|     // Notification Services for application | ||||
|     server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system)); | ||||
|     // Notification Services | ||||
|     server_manager->RegisterNamedService( | ||||
|         "notif:a", std::make_shared<INotificationServicesForApplication>(system)); | ||||
|     server_manager->RegisterNamedService("notif:s", | ||||
|                                          std::make_shared<INotificationServices>(system)); | ||||
|  | ||||
|     // Time | ||||
|     auto time = std::make_shared<Time::TimeManager>(system); | ||||
|   | ||||
| @@ -6,48 +6,31 @@ | ||||
|  | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/service/cmif_serialization.h" | ||||
| #include "core/hle/service/glue/notif.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
|  | ||||
| namespace Service::Glue { | ||||
|  | ||||
| NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {500, &NOTIF_A::RegisterAlarmSetting, "RegisterAlarmSetting"}, | ||||
|         {510, &NOTIF_A::UpdateAlarmSetting, "UpdateAlarmSetting"}, | ||||
|         {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, | ||||
|         {530, &NOTIF_A::LoadApplicationParameter, "LoadApplicationParameter"}, | ||||
|         {540, &NOTIF_A::DeleteAlarmSetting, "DeleteAlarmSetting"}, | ||||
|         {1000, &NOTIF_A::Initialize, "Initialize"}, | ||||
|     }; | ||||
|     // clang-format on | ||||
| namespace { | ||||
|  | ||||
| constexpr inline std::size_t MaxAlarms = 8; | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
|  | ||||
| NOTIF_A::~NOTIF_A() = default; | ||||
|  | ||||
| void NOTIF_A::RegisterAlarmSetting(HLERequestContext& ctx) { | ||||
|     const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||||
|     const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||||
|  | ||||
|     ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||||
|                "alarm_setting_buffer_size is not 0x40 bytes"); | ||||
|     ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||||
|                "application_parameter_size is bigger than 0x400 bytes"); | ||||
|  | ||||
|     AlarmSetting new_alarm{}; | ||||
|     memcpy(&new_alarm, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||||
|  | ||||
|     // TODO: Count alarms per game id | ||||
|     if (alarms.size() >= max_alarms) { | ||||
| Result NotificationServiceImpl::RegisterAlarmSetting(AlarmSettingId* out_alarm_setting_id, | ||||
|                                                      const AlarmSetting& alarm_setting, | ||||
|                                                      std::span<const u8> application_parameter) { | ||||
|     if (alarms.size() > MaxAlarms) { | ||||
|         LOG_ERROR(Service_NOTIF, "Alarm limit reached"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultUnknown); | ||||
|         return; | ||||
|         R_THROW(ResultUnknown); | ||||
|     } | ||||
|  | ||||
|     ASSERT_MSG(application_parameter.size() <= sizeof(ApplicationParameter), | ||||
|                "application_parameter_size is bigger than 0x400 bytes"); | ||||
|  | ||||
|     AlarmSetting new_alarm = alarm_setting; | ||||
|     new_alarm.alarm_setting_id = last_alarm_setting_id++; | ||||
|     alarms.push_back(new_alarm); | ||||
|  | ||||
| @@ -55,100 +38,82 @@ void NOTIF_A::RegisterAlarmSetting(HLERequestContext& ctx) { | ||||
|  | ||||
|     LOG_WARNING(Service_NOTIF, | ||||
|                 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||||
|                 application_parameter_size, new_alarm.alarm_setting_id, new_alarm.kind, | ||||
|                 application_parameter.size(), new_alarm.alarm_setting_id, new_alarm.kind, | ||||
|                 new_alarm.muted); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(new_alarm.alarm_setting_id); | ||||
|     *out_alarm_setting_id = new_alarm.alarm_setting_id; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| void NOTIF_A::UpdateAlarmSetting(HLERequestContext& ctx) { | ||||
|     const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||||
|     const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||||
|  | ||||
|     ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||||
|                "alarm_setting_buffer_size is not 0x40 bytes"); | ||||
|     ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||||
| Result NotificationServiceImpl::UpdateAlarmSetting(const AlarmSetting& alarm_setting, | ||||
|                                                    std::span<const u8> application_parameter) { | ||||
|     ASSERT_MSG(application_parameter.size() <= sizeof(ApplicationParameter), | ||||
|                "application_parameter_size is bigger than 0x400 bytes"); | ||||
|  | ||||
|     AlarmSetting alarm_setting{}; | ||||
|     memcpy(&alarm_setting, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||||
|  | ||||
|     const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id); | ||||
|     if (alarm_it != alarms.end()) { | ||||
|         LOG_DEBUG(Service_NOTIF, "Alarm updated"); | ||||
|         *alarm_it = alarm_setting; | ||||
|         // TODO: Save application parameter data | ||||
|     } | ||||
|  | ||||
|     LOG_WARNING(Service_NOTIF, | ||||
|                 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||||
|                 application_parameter_size, alarm_setting.alarm_setting_id, alarm_setting.kind, | ||||
|                 application_parameter.size(), alarm_setting.alarm_setting_id, alarm_setting.kind, | ||||
|                 alarm_setting.muted); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| void NOTIF_A::ListAlarmSettings(HLERequestContext& ctx) { | ||||
| Result NotificationServiceImpl::ListAlarmSettings(s32* out_count, | ||||
|                                                   std::span<AlarmSetting> out_alarms) { | ||||
|     LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); | ||||
|  | ||||
|     // TODO: Only return alarms of this game id | ||||
|     ctx.WriteBuffer(alarms); | ||||
|     const auto count = std::min(out_alarms.size(), alarms.size()); | ||||
|     for (size_t i = 0; i < count; i++) { | ||||
|         out_alarms[i] = alarms[i]; | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(static_cast<u32>(alarms.size())); | ||||
|     *out_count = static_cast<s32>(count); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| void NOTIF_A::LoadApplicationParameter(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||||
|  | ||||
| Result NotificationServiceImpl::LoadApplicationParameter(u32* out_size, | ||||
|                                                          std::span<u8> out_application_parameter, | ||||
|                                                          AlarmSettingId alarm_setting_id) { | ||||
|     const auto alarm_it = GetAlarmFromId(alarm_setting_id); | ||||
|     if (alarm_it == alarms.end()) { | ||||
|         LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultUnknown); | ||||
|         return; | ||||
|         R_THROW(ResultUnknown); | ||||
|     } | ||||
|  | ||||
|     // TODO: Read application parameter related to this setting id | ||||
|     ApplicationParameter application_parameter{}; | ||||
|  | ||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id); | ||||
|     std::memcpy(out_application_parameter.data(), application_parameter.data(), | ||||
|                 std::min(sizeof(application_parameter), out_application_parameter.size())); | ||||
|  | ||||
|     ctx.WriteBuffer(application_parameter); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(static_cast<u32>(application_parameter.size())); | ||||
|     *out_size = static_cast<u32>(application_parameter.size()); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| void NOTIF_A::DeleteAlarmSetting(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||||
|  | ||||
| Result NotificationServiceImpl::DeleteAlarmSetting(AlarmSettingId alarm_setting_id) { | ||||
|     std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { | ||||
|         return alarm.alarm_setting_id == alarm_setting_id; | ||||
|     }); | ||||
|  | ||||
|     LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| void NOTIF_A::Initialize(HLERequestContext& ctx) { | ||||
| Result NotificationServiceImpl::Initialize(u64 aruid) { | ||||
|     // TODO: Load previous alarms from config | ||||
|  | ||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( | ||||
| std::vector<AlarmSetting>::iterator NotificationServiceImpl::GetAlarmFromId( | ||||
|     AlarmSettingId alarm_setting_id) { | ||||
|     return std::find_if(alarms.begin(), alarms.end(), | ||||
|                         [alarm_setting_id](const AlarmSetting& alarm) { | ||||
| @@ -156,4 +121,174 @@ std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( | ||||
|                         }); | ||||
| } | ||||
|  | ||||
| INotificationServicesForApplication::INotificationServicesForApplication(Core::System& system_) | ||||
|     : ServiceFramework{system_, "notif:a"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {500, D<&INotificationServicesForApplication::RegisterAlarmSetting>, "RegisterAlarmSetting"}, | ||||
|         {510, D<&INotificationServicesForApplication::UpdateAlarmSetting>, "UpdateAlarmSetting"}, | ||||
|         {520, D<&INotificationServicesForApplication::ListAlarmSettings>, "ListAlarmSettings"}, | ||||
|         {530, D<&INotificationServicesForApplication::LoadApplicationParameter>, "LoadApplicationParameter"}, | ||||
|         {540, D<&INotificationServicesForApplication::DeleteAlarmSetting>, "DeleteAlarmSetting"}, | ||||
|         {1000, D<&INotificationServicesForApplication::Initialize>, "Initialize"}, | ||||
|     }; | ||||
|     // clang-format on | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
|  | ||||
| INotificationServicesForApplication::~INotificationServicesForApplication() = default; | ||||
|  | ||||
| Result INotificationServicesForApplication::RegisterAlarmSetting( | ||||
|     Out<AlarmSettingId> out_alarm_setting_id, | ||||
|     InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|     InBuffer<BufferAttr_HipcMapAlias> application_parameter) { | ||||
|     R_RETURN(impl.RegisterAlarmSetting(out_alarm_setting_id.Get(), *alarm_setting, | ||||
|                                        application_parameter)); | ||||
| } | ||||
|  | ||||
| Result INotificationServicesForApplication::UpdateAlarmSetting( | ||||
|     InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|     InBuffer<BufferAttr_HipcMapAlias> application_parameter) { | ||||
|     R_RETURN(impl.UpdateAlarmSetting(*alarm_setting, application_parameter)); | ||||
| } | ||||
|  | ||||
| Result INotificationServicesForApplication::ListAlarmSettings( | ||||
|     Out<s32> out_count, OutArray<AlarmSetting, BufferAttr_HipcMapAlias> out_alarms) { | ||||
|     R_RETURN(impl.ListAlarmSettings(out_count.Get(), out_alarms)); | ||||
| } | ||||
|  | ||||
| Result INotificationServicesForApplication::LoadApplicationParameter( | ||||
|     Out<u32> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_application_parameter, | ||||
|     AlarmSettingId alarm_setting_id) { | ||||
|     R_RETURN( | ||||
|         impl.LoadApplicationParameter(out_size.Get(), out_application_parameter, alarm_setting_id)); | ||||
| } | ||||
|  | ||||
| Result INotificationServicesForApplication::DeleteAlarmSetting(AlarmSettingId alarm_setting_id) { | ||||
|     R_RETURN(impl.DeleteAlarmSetting(alarm_setting_id)); | ||||
| } | ||||
|  | ||||
| Result INotificationServicesForApplication::Initialize(ClientAppletResourceUserId aruid) { | ||||
|     R_RETURN(impl.Initialize(*aruid)); | ||||
| } | ||||
|  | ||||
| class INotificationSystemEventAccessor final | ||||
|     : public ServiceFramework<INotificationSystemEventAccessor> { | ||||
| public: | ||||
|     explicit INotificationSystemEventAccessor(Core::System& system_) | ||||
|         : ServiceFramework{system_, "INotificationSystemEventAccessor"}, | ||||
|           service_context{system_, "INotificationSystemEventAccessor"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, D<&INotificationSystemEventAccessor::GetSystemEvent>, "GetSystemEvent"}, | ||||
|         }; | ||||
|         // clang-format on | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         notification_event = | ||||
|             service_context.CreateEvent("INotificationSystemEventAccessor:NotificationEvent"); | ||||
|     } | ||||
|  | ||||
|     ~INotificationSystemEventAccessor() { | ||||
|         service_context.CloseEvent(notification_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Result GetSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_readable_event) { | ||||
|         LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||||
|  | ||||
|         *out_readable_event = ¬ification_event->GetReadableEvent(); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     Kernel::KEvent* notification_event; | ||||
| }; | ||||
|  | ||||
| INotificationServices::INotificationServices(Core::System& system_) | ||||
|     : ServiceFramework{system_, "notif:s"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {500, D<&INotificationServices::RegisterAlarmSetting>, "RegisterAlarmSetting"}, | ||||
|         {510, D<&INotificationServices::UpdateAlarmSetting>, "UpdateAlarmSetting"}, | ||||
|         {520, D<&INotificationServices::ListAlarmSettings>, "ListAlarmSettings"}, | ||||
|         {530, D<&INotificationServices::LoadApplicationParameter>, "LoadApplicationParameter"}, | ||||
|         {540, D<&INotificationServices::DeleteAlarmSetting>, "DeleteAlarmSetting"}, | ||||
|         {1000, D<&INotificationServices::Initialize>, "Initialize"}, | ||||
|         {1010, nullptr, "ListNotifications"}, | ||||
|         {1020, nullptr, "DeleteNotification"}, | ||||
|         {1030, nullptr, "ClearNotifications"}, | ||||
|         {1040, D<&INotificationServices::OpenNotificationSystemEventAccessor>, "OpenNotificationSystemEventAccessor"}, | ||||
|         {1500, nullptr, "SetNotificationPresentationSetting"}, | ||||
|         {1510, D<&INotificationServices::GetNotificationPresentationSetting>, "GetNotificationPresentationSetting"}, | ||||
|         {2000, nullptr, "GetAlarmSetting"}, | ||||
|         {2001, nullptr, "GetAlarmSettingWithApplicationParameter"}, | ||||
|         {2010, nullptr, "MuteAlarmSetting"}, | ||||
|         {2020, nullptr, "IsAlarmSettingReady"}, | ||||
|         {8000, nullptr, "RegisterAppletResourceUserId"}, | ||||
|         {8010, nullptr, "UnregisterAppletResourceUserId"}, | ||||
|         {8999, nullptr, "GetCurrentTime"}, | ||||
|         {9000, nullptr, "GetAlarmSettingNextNotificationTime"}, | ||||
|     }; | ||||
|     // clang-format on | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
|  | ||||
| INotificationServices::~INotificationServices() = default; | ||||
|  | ||||
| Result INotificationServices::RegisterAlarmSetting( | ||||
|     Out<AlarmSettingId> out_alarm_setting_id, | ||||
|     InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|     InBuffer<BufferAttr_HipcMapAlias> application_parameter) { | ||||
|     R_RETURN(impl.RegisterAlarmSetting(out_alarm_setting_id.Get(), *alarm_setting, | ||||
|                                        application_parameter)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::UpdateAlarmSetting( | ||||
|     InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|     InBuffer<BufferAttr_HipcMapAlias> application_parameter) { | ||||
|     R_RETURN(impl.UpdateAlarmSetting(*alarm_setting, application_parameter)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::ListAlarmSettings( | ||||
|     Out<s32> out_count, OutArray<AlarmSetting, BufferAttr_HipcMapAlias> out_alarms) { | ||||
|     R_RETURN(impl.ListAlarmSettings(out_count.Get(), out_alarms)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::LoadApplicationParameter( | ||||
|     Out<u32> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_application_parameter, | ||||
|     AlarmSettingId alarm_setting_id) { | ||||
|     R_RETURN( | ||||
|         impl.LoadApplicationParameter(out_size.Get(), out_application_parameter, alarm_setting_id)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::DeleteAlarmSetting(AlarmSettingId alarm_setting_id) { | ||||
|     R_RETURN(impl.DeleteAlarmSetting(alarm_setting_id)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::Initialize(ClientAppletResourceUserId aruid) { | ||||
|     R_RETURN(impl.Initialize(*aruid)); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::OpenNotificationSystemEventAccessor( | ||||
|     Out<SharedPointer<INotificationSystemEventAccessor>> out_notification_system_event_accessor) { | ||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||||
|  | ||||
|     *out_notification_system_event_accessor = | ||||
|         std::make_shared<INotificationSystemEventAccessor>(system); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result INotificationServices::GetNotificationPresentationSetting( | ||||
|     Out<NotificationPresentationSetting> out_notification_presentation_setting, | ||||
|     NotificationChannel notification_channel) { | ||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||||
|  | ||||
|     *out_notification_presentation_setting = {}; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| } // namespace Service::Glue | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include <vector> | ||||
|  | ||||
| #include "common/uuid.h" | ||||
| #include "core/hle/service/cmif_types.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -15,58 +16,117 @@ class System; | ||||
|  | ||||
| namespace Service::Glue { | ||||
|  | ||||
| class NOTIF_A final : public ServiceFramework<NOTIF_A> { | ||||
| // This is nn::notification::AlarmSettingId | ||||
| using AlarmSettingId = u16; | ||||
| static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size"); | ||||
|  | ||||
| using ApplicationParameter = std::array<u8, 0x400>; | ||||
| static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size"); | ||||
|  | ||||
| struct DailyAlarmSetting { | ||||
|     s8 hour; | ||||
|     s8 minute; | ||||
| }; | ||||
| static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size"); | ||||
|  | ||||
| struct WeeklyScheduleAlarmSetting { | ||||
|     INSERT_PADDING_BYTES_NOINIT(0xA); | ||||
|     std::array<DailyAlarmSetting, 0x7> day_of_week; | ||||
| }; | ||||
| static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18, | ||||
|               "WeeklyScheduleAlarmSetting is an invalid size"); | ||||
|  | ||||
| // This is nn::notification::AlarmSetting | ||||
| struct AlarmSetting { | ||||
|     AlarmSettingId alarm_setting_id; | ||||
|     u8 kind; | ||||
|     u8 muted; | ||||
|     INSERT_PADDING_BYTES_NOINIT(0x4); | ||||
|     Common::UUID account_id; | ||||
|     u64 application_id; | ||||
|     INSERT_PADDING_BYTES_NOINIT(0x8); | ||||
|     WeeklyScheduleAlarmSetting schedule; | ||||
| }; | ||||
| static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); | ||||
|  | ||||
| enum class NotificationChannel : u8 { | ||||
|     Unknown0 = 0, | ||||
| }; | ||||
|  | ||||
| struct NotificationPresentationSetting { | ||||
|     INSERT_PADDING_BYTES_NOINIT(0x10); | ||||
| }; | ||||
| static_assert(sizeof(NotificationPresentationSetting) == 0x10, | ||||
|               "NotificationPresentationSetting is an invalid size"); | ||||
|  | ||||
| class NotificationServiceImpl { | ||||
| public: | ||||
|     explicit NOTIF_A(Core::System& system_); | ||||
|     ~NOTIF_A() override; | ||||
|     Result RegisterAlarmSetting(AlarmSettingId* out_alarm_setting_id, | ||||
|                                 const AlarmSetting& alarm_setting, | ||||
|                                 std::span<const u8> application_parameter); | ||||
|     Result UpdateAlarmSetting(const AlarmSetting& alarm_setting, | ||||
|                               std::span<const u8> application_parameter); | ||||
|     Result ListAlarmSettings(s32* out_count, std::span<AlarmSetting> out_alarms); | ||||
|     Result LoadApplicationParameter(u32* out_size, std::span<u8> out_application_parameter, | ||||
|                                     AlarmSettingId alarm_setting_id); | ||||
|     Result DeleteAlarmSetting(AlarmSettingId alarm_setting_id); | ||||
|     Result Initialize(u64 aruid); | ||||
|  | ||||
| private: | ||||
|     static constexpr std::size_t max_alarms = 8; | ||||
|  | ||||
|     // This is nn::notification::AlarmSettingId | ||||
|     using AlarmSettingId = u16; | ||||
|     static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size"); | ||||
|  | ||||
|     using ApplicationParameter = std::array<u8, 0x400>; | ||||
|     static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size"); | ||||
|  | ||||
|     struct DailyAlarmSetting { | ||||
|         s8 hour; | ||||
|         s8 minute; | ||||
|     }; | ||||
|     static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size"); | ||||
|  | ||||
|     struct WeeklyScheduleAlarmSetting { | ||||
|         INSERT_PADDING_BYTES(0xA); | ||||
|         std::array<DailyAlarmSetting, 0x7> day_of_week; | ||||
|     }; | ||||
|     static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18, | ||||
|                   "WeeklyScheduleAlarmSetting is an invalid size"); | ||||
|  | ||||
|     // This is nn::notification::AlarmSetting | ||||
|     struct AlarmSetting { | ||||
|         AlarmSettingId alarm_setting_id; | ||||
|         u8 kind; | ||||
|         u8 muted; | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|         Common::UUID account_id; | ||||
|         u64 application_id; | ||||
|         INSERT_PADDING_BYTES(0x8); | ||||
|         WeeklyScheduleAlarmSetting schedule; | ||||
|     }; | ||||
|     static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); | ||||
|  | ||||
|     void RegisterAlarmSetting(HLERequestContext& ctx); | ||||
|     void UpdateAlarmSetting(HLERequestContext& ctx); | ||||
|     void ListAlarmSettings(HLERequestContext& ctx); | ||||
|     void LoadApplicationParameter(HLERequestContext& ctx); | ||||
|     void DeleteAlarmSetting(HLERequestContext& ctx); | ||||
|     void Initialize(HLERequestContext& ctx); | ||||
|  | ||||
|     std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); | ||||
|  | ||||
|     std::vector<AlarmSetting> alarms{}; | ||||
|     AlarmSettingId last_alarm_setting_id{}; | ||||
| }; | ||||
|  | ||||
| class INotificationServicesForApplication final | ||||
|     : public ServiceFramework<INotificationServicesForApplication> { | ||||
| public: | ||||
|     explicit INotificationServicesForApplication(Core::System& system_); | ||||
|     ~INotificationServicesForApplication() override; | ||||
|  | ||||
| private: | ||||
|     Result RegisterAlarmSetting(Out<AlarmSettingId> out_alarm_setting_id, | ||||
|                                 InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|                                 InBuffer<BufferAttr_HipcMapAlias> application_parameter); | ||||
|     Result UpdateAlarmSetting(InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|                               InBuffer<BufferAttr_HipcMapAlias> application_parameter); | ||||
|     Result ListAlarmSettings(Out<s32> out_count, | ||||
|                              OutArray<AlarmSetting, BufferAttr_HipcMapAlias> out_alarms); | ||||
|     Result LoadApplicationParameter(Out<u32> out_size, | ||||
|                                     OutBuffer<BufferAttr_HipcMapAlias> out_application_parameter, | ||||
|                                     AlarmSettingId alarm_setting_id); | ||||
|     Result DeleteAlarmSetting(AlarmSettingId alarm_setting_id); | ||||
|     Result Initialize(ClientAppletResourceUserId aruid); | ||||
|  | ||||
|     NotificationServiceImpl impl; | ||||
| }; | ||||
|  | ||||
| class INotificationSystemEventAccessor; | ||||
|  | ||||
| class INotificationServices final : public ServiceFramework<INotificationServices> { | ||||
| public: | ||||
|     explicit INotificationServices(Core::System& system_); | ||||
|     ~INotificationServices() override; | ||||
|  | ||||
| private: | ||||
|     Result RegisterAlarmSetting(Out<AlarmSettingId> out_alarm_setting_id, | ||||
|                                 InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|                                 InBuffer<BufferAttr_HipcMapAlias> application_parameter); | ||||
|     Result UpdateAlarmSetting(InLargeData<AlarmSetting, BufferAttr_HipcMapAlias> alarm_setting, | ||||
|                               InBuffer<BufferAttr_HipcMapAlias> application_parameter); | ||||
|     Result ListAlarmSettings(Out<s32> out_count, | ||||
|                              OutArray<AlarmSetting, BufferAttr_HipcMapAlias> out_alarms); | ||||
|     Result LoadApplicationParameter(Out<u32> out_size, | ||||
|                                     OutBuffer<BufferAttr_HipcMapAlias> out_application_parameter, | ||||
|                                     AlarmSettingId alarm_setting_id); | ||||
|     Result DeleteAlarmSetting(AlarmSettingId alarm_setting_id); | ||||
|     Result Initialize(ClientAppletResourceUserId aruid); | ||||
|     Result OpenNotificationSystemEventAccessor(Out<SharedPointer<INotificationSystemEventAccessor>> | ||||
|                                                    out_notification_system_event_accessor); | ||||
|     Result GetNotificationPresentationSetting( | ||||
|         Out<NotificationPresentationSetting> out_notification_presentation_setting, | ||||
|         NotificationChannel notification_channel); | ||||
|  | ||||
|     NotificationServiceImpl impl; | ||||
| }; | ||||
| } // namespace Service::Glue | ||||
|   | ||||
		Reference in New Issue
	
	Block a user