summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar David Marcec2019-06-24 12:26:45 +1000
committerGravatar David Marcec2019-06-24 12:26:45 +1000
commite49ae3bf92fdc3f925ceaff03c4f2b9e90f94448 (patch)
treeecaf6c49c7ed16728a9419354e630b6f1d4ac3fc /src
parentMerge pull request #2603 from WamWooWam/master (diff)
downloadyuzu-e49ae3bf92fdc3f925ceaff03c4f2b9e90f94448.tar.gz
yuzu-e49ae3bf92fdc3f925ceaff03c4f2b9e90f94448.tar.xz
yuzu-e49ae3bf92fdc3f925ceaff03c4f2b9e90f94448.zip
Implemented INotificationService
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/service/friend/errors.h12
-rw-r--r--src/core/hle/service/friend/friend.cpp112
-rw-r--r--src/core/hle/service/friend/friend.h1
-rw-r--r--src/core/hle/service/friend/interface.cpp2
5 files changed, 127 insertions, 1 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cdb3bf6ab..2ccd4a779 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -272,6 +272,7 @@ add_library(core STATIC
272 hle/service/filesystem/fsp_srv.h 272 hle/service/filesystem/fsp_srv.h
273 hle/service/fgm/fgm.cpp 273 hle/service/fgm/fgm.cpp
274 hle/service/fgm/fgm.h 274 hle/service/fgm/fgm.h
275 hle/service/friend/errors.h
275 hle/service/friend/friend.cpp 276 hle/service/friend/friend.cpp
276 hle/service/friend/friend.h 277 hle/service/friend/friend.h
277 hle/service/friend/interface.cpp 278 hle/service/friend/interface.cpp
diff --git a/src/core/hle/service/friend/errors.h b/src/core/hle/service/friend/errors.h
new file mode 100644
index 000000000..72d96b555
--- /dev/null
+++ b/src/core/hle/service/friend/errors.h
@@ -0,0 +1,12 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/result.h"
8
9namespace Service::Friend {
10
11constexpr ResultCode ERR_NO_NOTIFICATIONS{ErrorModule::Account, 15};
12}
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 5100e376c..9752f1a8d 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -2,8 +2,13 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <queue>
5#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/uuid.h"
6#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/readable_event.h"
10#include "core/hle/kernel/writable_event.h"
11#include "core/hle/service/friend/errors.h"
7#include "core/hle/service/friend/friend.h" 12#include "core/hle/service/friend/friend.h"
8#include "core/hle/service/friend/interface.h" 13#include "core/hle/service/friend/interface.h"
9 14
@@ -109,6 +114,103 @@ private:
109 } 114 }
110}; 115};
111 116
117class INotificationService final : public ServiceFramework<INotificationService> {
118public:
119 INotificationService(Common::UUID uuid) : ServiceFramework("INotificationService"), uuid(uuid) {
120 // clang-format off
121 static const FunctionInfo functions[] = {
122 {0, &INotificationService::GetEvent, "GetEvent"},
123 {1, &INotificationService::Clear, "Clear"},
124 {2, &INotificationService::Pop, "Pop"}
125 };
126 // clang-format on
127
128 RegisterHandlers(functions);
129 }
130
131private:
132 void GetEvent(Kernel::HLERequestContext& ctx) {
133 LOG_DEBUG(Service_ACC, "called");
134
135 IPC::ResponseBuilder rb{ctx, 2, 1};
136 rb.Push(RESULT_SUCCESS);
137
138 if (is_event_created) {
139 rb.PushCopyObjects(notification_event.readable);
140 } else {
141 auto& kernel = Core::System::GetInstance().Kernel();
142 notification_event = Kernel::WritableEvent::CreateEventPair(
143 kernel, Kernel::ResetType::Manual, "INotificationService:NotifyEvent");
144 is_event_created = true;
145 rb.PushCopyObjects(notification_event.readable);
146 }
147 }
148
149 void Clear(Kernel::HLERequestContext& ctx) {
150 LOG_DEBUG(Service_ACC, "called");
151 while (!notifications.empty()) {
152 notifications.pop();
153 }
154 states.has_recieved_friend_request = false;
155 states.has_updated_friends = false;
156
157 IPC::ResponseBuilder rb{ctx, 2};
158 rb.Push(RESULT_SUCCESS);
159 }
160
161 void Pop(Kernel::HLERequestContext& ctx) {
162 LOG_DEBUG(Service_ACC, "called");
163 IPC::ResponseBuilder rb{ctx, 2};
164
165 if (notifications.empty()) {
166 LOG_ERROR(Service_ACC, "No notifications in queue!");
167 rb.Push(ERR_NO_NOTIFICATIONS);
168 return;
169 }
170
171 auto notification = notifications.front();
172 notifications.pop();
173
174 switch (notification.notification_type) {
175 case NotificationTypes::HasUpdatedFriendsList:
176 states.has_updated_friends = false;
177 break;
178 case NotificationTypes::HasRecievedFriendRequest:
179 states.has_recieved_friend_request = false;
180 break;
181 default:
182 // HOS seems not have an error case for an unknown notification
183 LOG_WARNING(Service_ACC, "Unknown notification {:08X}",
184 static_cast<u32>(notification.notification_type));
185 break;
186 }
187 rb.Push(RESULT_SUCCESS);
188 }
189
190 enum class NotificationTypes : u32_le {
191 HasUpdatedFriendsList = 0x65,
192 HasRecievedFriendRequest = 0x1
193 };
194
195 struct SizedNotificationInfo {
196 NotificationTypes notification_type;
197 INSERT_PADDING_WORDS(
198 1); // TODO(ogniK): This doesn't seem to be used within any IPC returns as of now
199 Common::UUID user_uuid;
200 };
201
202 struct States {
203 bool has_updated_friends;
204 bool has_recieved_friend_request;
205 };
206
207 Common::UUID uuid{};
208 bool is_event_created = false;
209 Kernel::EventPair notification_event;
210 std::queue<SizedNotificationInfo> notifications{};
211 States states{};
212};
213
112void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { 214void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
113 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 215 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
114 rb.Push(RESULT_SUCCESS); 216 rb.Push(RESULT_SUCCESS);
@@ -116,6 +218,16 @@ void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
116 LOG_DEBUG(Service_ACC, "called"); 218 LOG_DEBUG(Service_ACC, "called");
117} 219}
118 220
221void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx) {
222 IPC::RequestParser rp{ctx};
223 auto uuid = rp.PopRaw<Common::UUID>();
224
225 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
226 rb.Push(RESULT_SUCCESS);
227 rb.PushIpcInterface<INotificationService>(uuid);
228 LOG_DEBUG(Service_ACC, "called");
229}
230
119Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 231Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
120 : ServiceFramework(name), module(std::move(module)) {} 232 : ServiceFramework(name), module(std::move(module)) {}
121 233
diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h
index e762840cb..38d05fa8e 100644
--- a/src/core/hle/service/friend/friend.h
+++ b/src/core/hle/service/friend/friend.h
@@ -16,6 +16,7 @@ public:
16 ~Interface() override; 16 ~Interface() override;
17 17
18 void CreateFriendService(Kernel::HLERequestContext& ctx); 18 void CreateFriendService(Kernel::HLERequestContext& ctx);
19 void CreateNotificationService(Kernel::HLERequestContext& ctx);
19 20
20 protected: 21 protected:
21 std::shared_ptr<Module> module; 22 std::shared_ptr<Module> module;
diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/interface.cpp
index 5a6840af5..5b384f733 100644
--- a/src/core/hle/service/friend/interface.cpp
+++ b/src/core/hle/service/friend/interface.cpp
@@ -10,7 +10,7 @@ Friend::Friend(std::shared_ptr<Module> module, const char* name)
10 : Interface(std::move(module), name) { 10 : Interface(std::move(module), name) {
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, &Friend::CreateFriendService, "CreateFriendService"}, 12 {0, &Friend::CreateFriendService, "CreateFriendService"},
13 {1, nullptr, "CreateNotificationService"}, 13 {1, &Friend::CreateNotificationService, "CreateNotificationService"},
14 {2, nullptr, "CreateDaemonSuspendSessionService"}, 14 {2, nullptr, "CreateDaemonSuspendSessionService"},
15 }; 15 };
16 RegisterHandlers(functions); 16 RegisterHandlers(functions);