mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
system service: deliver initial AppContent entitlement updates through shared queue
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include "common/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "libs/errno.h"
|
#include "libs/errno.h"
|
||||||
#include "libs/libs.h"
|
#include "libs/libs.h"
|
||||||
|
#include "libs/systemService.h"
|
||||||
#include "loader/symbolDatabase.h"
|
#include "loader/symbolDatabase.h"
|
||||||
#include "loader/systemContent.h"
|
#include "loader/systemContent.h"
|
||||||
|
|
||||||
@@ -96,6 +97,7 @@ int KYTY_SYSV_ABI AppContentInitialize(const AppContentInitParam* init_param,
|
|||||||
LOGF("\t TITLE_ID missing\n");
|
LOGF("\t TITLE_ID missing\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemService::NotifyEntitlementUpdate();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,12 @@
|
|||||||
#include "libs/dialog.h"
|
#include "libs/dialog.h"
|
||||||
#include "libs/errno.h"
|
#include "libs/errno.h"
|
||||||
#include "libs/libs.h"
|
#include "libs/libs.h"
|
||||||
|
#include "libs/systemService.h"
|
||||||
#include "loader/symbolDatabase.h"
|
#include "loader/symbolDatabase.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <deque>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace Libs {
|
namespace Libs {
|
||||||
|
|
||||||
@@ -70,6 +73,14 @@ struct SystemServiceEvent {
|
|||||||
uint8_t data[8192];
|
uint8_t data[8192];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::mutex g_event_mutex;
|
||||||
|
static std::deque<int32_t> g_events;
|
||||||
|
|
||||||
|
void NotifyEntitlementUpdate() {
|
||||||
|
std::scoped_lock lock(g_event_mutex);
|
||||||
|
g_events.push_back(0x10000003); // SCE_SYSTEM_SERVICE_EVENT_ENTITLEMENT_UPDATE
|
||||||
|
}
|
||||||
|
|
||||||
struct SystemServiceDisplaySafeAreaInfo {
|
struct SystemServiceDisplaySafeAreaInfo {
|
||||||
float ratio;
|
float ratio;
|
||||||
uint8_t reserved[128];
|
uint8_t reserved[128];
|
||||||
@@ -153,7 +164,14 @@ static int KYTY_SYSV_ABI SystemServiceReceiveEvent(SystemServiceEvent* event) {
|
|||||||
event->event_type = -1;
|
event->event_type = -1;
|
||||||
std::memset(event->data, 0, sizeof(event->data));
|
std::memset(event->data, 0, sizeof(event->data));
|
||||||
|
|
||||||
return SYSTEM_SERVICE_ERROR_NO_EVENT;
|
std::scoped_lock lock(g_event_mutex);
|
||||||
|
if (g_events.empty()) {
|
||||||
|
return SYSTEM_SERVICE_ERROR_NO_EVENT;
|
||||||
|
}
|
||||||
|
event->event_type = g_events.front();
|
||||||
|
g_events.pop_front();
|
||||||
|
LOGF("\t SystemService event = 0x%08x\n", static_cast<uint32_t>(event->event_type));
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int KYTY_SYSV_ABI SystemServiceGetStatus(SystemServiceStatus* status) {
|
static int KYTY_SYSV_ABI SystemServiceGetStatus(SystemServiceStatus* status) {
|
||||||
@@ -167,6 +185,10 @@ static int KYTY_SYSV_ABI SystemServiceGetStatus(SystemServiceStatus* status) {
|
|||||||
*status = SystemServiceStatus();
|
*status = SystemServiceStatus();
|
||||||
status->is_system_ui_overlaid = dialog.active;
|
status->is_system_ui_overlaid = dialog.active;
|
||||||
status->is_in_background_execution = dialog.background;
|
status->is_in_background_execution = dialog.background;
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(g_event_mutex);
|
||||||
|
status->event_num = static_cast<int32_t>(g_events.size());
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef EMULATOR_LIBS_SYSTEMSERVICE_H_
|
||||||
|
#define EMULATOR_LIBS_SYSTEMSERVICE_H_
|
||||||
|
|
||||||
|
namespace Libs::SystemService {
|
||||||
|
|
||||||
|
void NotifyEntitlementUpdate();
|
||||||
|
|
||||||
|
} // namespace Libs::SystemService
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -46,6 +46,8 @@ void InitLibKernel_1_Apr(Loader::SymbolDatabase *symbols);
|
|||||||
namespace Libs {
|
namespace Libs {
|
||||||
void InitLibKernel_1(Loader::SymbolDatabase *symbols);
|
void InitLibKernel_1(Loader::SymbolDatabase *symbols);
|
||||||
void InitSysmodule_1(Loader::SymbolDatabase *symbols);
|
void InitSysmodule_1(Loader::SymbolDatabase *symbols);
|
||||||
|
void InitSystemService_1(Loader::SymbolDatabase *symbols);
|
||||||
|
void InitAppContent_1(Loader::SymbolDatabase *symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Libs::LibAmpr {
|
namespace Libs::LibAmpr {
|
||||||
@@ -204,6 +206,56 @@ void TestSysmoduleReferences() {
|
|||||||
"internal and public module operations share load state");
|
"internal and public module operations share load state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSystemServiceEntitlementEvents() {
|
||||||
|
Loader::SymbolDatabase symbols;
|
||||||
|
Libs::InitSystemService_1(&symbols);
|
||||||
|
Libs::InitAppContent_1(&symbols);
|
||||||
|
const auto resolve = [&](const char* nid, const char* library, const char* module) {
|
||||||
|
const auto* symbol = symbols.Find(
|
||||||
|
{nid, library, 1, module, 1, 1, Loader::SymbolType::Func});
|
||||||
|
Check(symbol != nullptr, "entitlement event export resolves");
|
||||||
|
return symbol->vaddr;
|
||||||
|
};
|
||||||
|
const auto initialize = reinterpret_cast<int (KYTY_SYSV_ABI *)(const void*, void*)>(
|
||||||
|
resolve("R9lA82OraNs", "AppContent", "AppContentUtil"));
|
||||||
|
struct Status {
|
||||||
|
int32_t event_num;
|
||||||
|
bool overlay, background, vr;
|
||||||
|
uint8_t reserved[127];
|
||||||
|
};
|
||||||
|
struct Event {
|
||||||
|
int32_t type;
|
||||||
|
uint8_t data[8192];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Status) == 136 && sizeof(Event) == 8196);
|
||||||
|
const auto get_status = reinterpret_cast<int (KYTY_SYSV_ABI *)(Status*)>(
|
||||||
|
resolve("rPo6tV8D9bM", "SystemService", "SystemService"));
|
||||||
|
const auto receive = reinterpret_cast<int (KYTY_SYSV_ABI *)(Event*)>(
|
||||||
|
resolve("656LMQSrg6U", "SystemService", "SystemService"));
|
||||||
|
Status status {};
|
||||||
|
Event event {};
|
||||||
|
Check(get_status(&status) == OK && status.event_num == 0,
|
||||||
|
"SystemService starts without pending events");
|
||||||
|
std::array<uint8_t, 32> init {};
|
||||||
|
std::array<uint8_t, 40> boot {};
|
||||||
|
Check(initialize(init.data(), boot.data()) == OK,
|
||||||
|
"AppContent initialization generates an entitlement notification");
|
||||||
|
Check(get_status(&status) == OK && status.event_num == 1 &&
|
||||||
|
get_status(&status) == OK && status.event_num == 1,
|
||||||
|
"status queries preserve pending notifications");
|
||||||
|
Check(receive(nullptr) == Libs::SystemService::SYSTEM_SERVICE_ERROR_PARAMETER &&
|
||||||
|
get_status(&status) == OK && status.event_num == 1,
|
||||||
|
"invalid event output does not consume a notification");
|
||||||
|
std::memset(&event, 0xff, sizeof(event));
|
||||||
|
Check(receive(&event) == OK && event.type == 0x10000003 &&
|
||||||
|
std::all_of(std::begin(event.data), std::end(event.data),
|
||||||
|
[](uint8_t byte) { return byte == 0; }) &&
|
||||||
|
get_status(&status) == OK && status.event_num == 0,
|
||||||
|
"receive delivers the entitlement event with cleared payload exactly once");
|
||||||
|
Check(receive(&event) == Libs::SystemService::SYSTEM_SERVICE_ERROR_NO_EVENT,
|
||||||
|
"empty event queue reports NO_EVENT");
|
||||||
|
}
|
||||||
|
|
||||||
void TestSaveOpenVisibility() {
|
void TestSaveOpenVisibility() {
|
||||||
constexpr char Path[] = "/savedata0/visible-save.dat";
|
constexpr char Path[] = "/savedata0/visible-save.dat";
|
||||||
constexpr char Payload[] = "saved progress";
|
constexpr char Payload[] = "saved progress";
|
||||||
@@ -1573,6 +1625,7 @@ int main(int, char**) {
|
|||||||
TempDirectory temporary;
|
TempDirectory temporary;
|
||||||
FileSystem::Initialize();
|
FileSystem::Initialize();
|
||||||
TestSysmoduleReferences();
|
TestSysmoduleReferences();
|
||||||
|
TestSystemServiceEntitlementEvents();
|
||||||
TestRandomDevices();
|
TestRandomDevices();
|
||||||
TestFileDescriptorFlags();
|
TestFileDescriptorFlags();
|
||||||
CheckMountRoot(temporary.Path());
|
CheckMountRoot(temporary.Path());
|
||||||
|
|||||||
Reference in New Issue
Block a user