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 |     // Error Context | ||||||
|     server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system)); |     server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system)); | ||||||
|  |  | ||||||
|     // Notification Services for application |     // Notification Services | ||||||
|     server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system)); |     server_manager->RegisterNamedService( | ||||||
|  |         "notif:a", std::make_shared<INotificationServicesForApplication>(system)); | ||||||
|  |     server_manager->RegisterNamedService("notif:s", | ||||||
|  |                                          std::make_shared<INotificationServices>(system)); | ||||||
|  |  | ||||||
|     // Time |     // Time | ||||||
|     auto time = std::make_shared<Time::TimeManager>(system); |     auto time = std::make_shared<Time::TimeManager>(system); | ||||||
|   | |||||||
| @@ -6,48 +6,31 @@ | |||||||
|  |  | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
| #include "core/hle/service/glue/notif.h" | #include "core/hle/service/glue/notif.h" | ||||||
| #include "core/hle/service/ipc_helpers.h" | #include "core/hle/service/ipc_helpers.h" | ||||||
|  | #include "core/hle/service/kernel_helpers.h" | ||||||
|  |  | ||||||
| namespace Service::Glue { | namespace Service::Glue { | ||||||
|  |  | ||||||
| NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | namespace { | ||||||
|     // clang-format off |  | ||||||
|     static const FunctionInfo functions[] = { | constexpr inline std::size_t MaxAlarms = 8; | ||||||
|         {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 |  | ||||||
|  |  | ||||||
|     RegisterHandlers(functions); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| NOTIF_A::~NOTIF_A() = default; | Result NotificationServiceImpl::RegisterAlarmSetting(AlarmSettingId* out_alarm_setting_id, | ||||||
|  |                                                      const AlarmSetting& alarm_setting, | ||||||
| void NOTIF_A::RegisterAlarmSetting(HLERequestContext& ctx) { |                                                      std::span<const u8> application_parameter) { | ||||||
|     const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); |     if (alarms.size() > MaxAlarms) { | ||||||
|     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) { |  | ||||||
|         LOG_ERROR(Service_NOTIF, "Alarm limit reached"); |         LOG_ERROR(Service_NOTIF, "Alarm limit reached"); | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |         R_THROW(ResultUnknown); | ||||||
|         rb.Push(ResultUnknown); |  | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     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++; |     new_alarm.alarm_setting_id = last_alarm_setting_id++; | ||||||
|     alarms.push_back(new_alarm); |     alarms.push_back(new_alarm); | ||||||
|  |  | ||||||
| @@ -55,100 +38,82 @@ void NOTIF_A::RegisterAlarmSetting(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     LOG_WARNING(Service_NOTIF, |     LOG_WARNING(Service_NOTIF, | ||||||
|                 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", |                 "(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); |                 new_alarm.muted); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     *out_alarm_setting_id = new_alarm.alarm_setting_id; | ||||||
|     rb.Push(ResultSuccess); |     R_SUCCEED(); | ||||||
|     rb.Push(new_alarm.alarm_setting_id); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void NOTIF_A::UpdateAlarmSetting(HLERequestContext& ctx) { | Result NotificationServiceImpl::UpdateAlarmSetting(const AlarmSetting& alarm_setting, | ||||||
|     const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); |                                                    std::span<const u8> application_parameter) { | ||||||
|     const auto application_parameter_size = ctx.GetReadBufferSize(1); |     ASSERT_MSG(application_parameter.size() <= sizeof(ApplicationParameter), | ||||||
|  |  | ||||||
|     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"); |                "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); |     const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id); | ||||||
|     if (alarm_it != alarms.end()) { |     if (alarm_it != alarms.end()) { | ||||||
|         LOG_DEBUG(Service_NOTIF, "Alarm updated"); |         LOG_DEBUG(Service_NOTIF, "Alarm updated"); | ||||||
|         *alarm_it = alarm_setting; |         *alarm_it = alarm_setting; | ||||||
|         // TODO: Save application parameter data |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     LOG_WARNING(Service_NOTIF, |     LOG_WARNING(Service_NOTIF, | ||||||
|                 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", |                 "(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); |                 alarm_setting.muted); | ||||||
|  |     R_SUCCEED(); | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| 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()); |     LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); | ||||||
|  |  | ||||||
|     // TODO: Only return alarms of this game id |     const auto count = std::min(out_alarms.size(), alarms.size()); | ||||||
|     ctx.WriteBuffer(alarms); |     for (size_t i = 0; i < count; i++) { | ||||||
|  |         out_alarms[i] = alarms[i]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     *out_count = static_cast<s32>(count); | ||||||
|     rb.Push(ResultSuccess); |     R_SUCCEED(); | ||||||
|     rb.Push(static_cast<u32>(alarms.size())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void NOTIF_A::LoadApplicationParameter(HLERequestContext& ctx) { | Result NotificationServiceImpl::LoadApplicationParameter(u32* out_size, | ||||||
|     IPC::RequestParser rp{ctx}; |                                                          std::span<u8> out_application_parameter, | ||||||
|     const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; |                                                          AlarmSettingId alarm_setting_id) { | ||||||
|  |  | ||||||
|     const auto alarm_it = GetAlarmFromId(alarm_setting_id); |     const auto alarm_it = GetAlarmFromId(alarm_setting_id); | ||||||
|     if (alarm_it == alarms.end()) { |     if (alarm_it == alarms.end()) { | ||||||
|         LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); |         LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |         R_THROW(ResultUnknown); | ||||||
|         rb.Push(ResultUnknown); |  | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO: Read application parameter related to this setting id |     // TODO: Read application parameter related to this setting id | ||||||
|     ApplicationParameter application_parameter{}; |     ApplicationParameter application_parameter{}; | ||||||
|  |  | ||||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id); |     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); |     *out_size = static_cast<u32>(application_parameter.size()); | ||||||
|  |     R_SUCCEED(); | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
|     rb.Push(static_cast<u32>(application_parameter.size())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void NOTIF_A::DeleteAlarmSetting(HLERequestContext& ctx) { | Result NotificationServiceImpl::DeleteAlarmSetting(AlarmSettingId alarm_setting_id) { | ||||||
|     IPC::RequestParser rp{ctx}; |  | ||||||
|     const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; |  | ||||||
|  |  | ||||||
|     std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { |     std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { | ||||||
|         return alarm.alarm_setting_id == alarm_setting_id; |         return alarm.alarm_setting_id == alarm_setting_id; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); |     LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     R_SUCCEED(); | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void NOTIF_A::Initialize(HLERequestContext& ctx) { | Result NotificationServiceImpl::Initialize(u64 aruid) { | ||||||
|     // TODO: Load previous alarms from config |     // TODO: Load previous alarms from config | ||||||
|  |  | ||||||
|     LOG_WARNING(Service_NOTIF, "(STUBBED) called"); |     LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     R_SUCCEED(); | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( | std::vector<AlarmSetting>::iterator NotificationServiceImpl::GetAlarmFromId( | ||||||
|     AlarmSettingId alarm_setting_id) { |     AlarmSettingId alarm_setting_id) { | ||||||
|     return std::find_if(alarms.begin(), alarms.end(), |     return std::find_if(alarms.begin(), alarms.end(), | ||||||
|                         [alarm_setting_id](const AlarmSetting& alarm) { |                         [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 | } // namespace Service::Glue | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| #include "common/uuid.h" | #include "common/uuid.h" | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
| namespace Core { | namespace Core { | ||||||
| @@ -15,58 +16,117 @@ class System; | |||||||
|  |  | ||||||
| namespace Service::Glue { | 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: | public: | ||||||
|     explicit NOTIF_A(Core::System& system_); |     Result RegisterAlarmSetting(AlarmSettingId* out_alarm_setting_id, | ||||||
|     ~NOTIF_A() override; |                                 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: | 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>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); | ||||||
|  |  | ||||||
|     std::vector<AlarmSetting> alarms{}; |     std::vector<AlarmSetting> alarms{}; | ||||||
|     AlarmSettingId last_alarm_setting_id{}; |     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 | } // namespace Service::Glue | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user