mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
AnyPS5 has no shell UI: sceSystemServiceGetStatus never reports a system UI overlay or background execution, and the host has no auto power-off timer. The shell UI therefore never takes the foreground, overlays the impose screen, runs a screen saver or shuts down, and those queries return false. libSceHmd detects no headset, so there is no PS VR social screen and the logged-in user's eye-to-eye distance was never adjusted. Another user ID throws, since the console's error for it is not measured. The sceSystemService twins forward to their sceShellCoreUtil and sceLncUtil targets. sceSystemServiceIsEyeToEyeDistanceAdjusted returns SYSTEM_SERVICE_ERROR_PARAMETER for a null output before forwarding, as its neighbours do, and the sceShellCoreUtil forms throw for one.
172 lines
8.2 KiB
C++
172 lines
8.2 KiB
C++
#include "SceTypes.hpp"
|
|
#include "prx/libSceSystemService/SystemService.hpp"
|
|
#include "prx/libSceUserService/UserService.hpp"
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <exception>
|
|
#include <initializer_list>
|
|
#include <stdexcept>
|
|
#include <string_view>
|
|
|
|
extern "C" int APS5_VABI sceLncUtilBlockAppSuspend(const char* reason);
|
|
extern "C" int APS5_VABI sceLncUtilUnblockAppSuspend(const char* reason);
|
|
extern "C" int APS5_VABI sceLncUtilEnableSuspendNotification();
|
|
extern "C" int APS5_VABI sceLncUtilDisableSuspendNotification();
|
|
extern "C" int APS5_VABI sceSystemServiceEnableSuspendNotification();
|
|
extern "C" int APS5_VABI sceSystemServiceDisableSuspendNotification();
|
|
extern "C" int APS5_VABI sceShellCoreUtilGetRemotePlayStatus(bool* active);
|
|
extern "C" int APS5_VABI sceSystemServiceGetRemoteplayStatus(bool* active);
|
|
extern "C" int APS5_VABI sceShellCoreUtilGetSharePlayStatus(bool* active);
|
|
extern "C" int APS5_VABI sceShellCoreUtilGetGameLiveStreamingStatus(bool* active);
|
|
extern "C" bool APS5_VABI sceShellCoreUtilIsGameLiveStreamingOnAir();
|
|
extern "C" bool APS5_VABI sceSystemServiceIsGameLiveStreamingOnAir();
|
|
extern "C" bool APS5_VABI sceLncUtilIsShellUiFgAndGameBgCpuMode();
|
|
extern "C" bool APS5_VABI sceSystemServiceIsShellUiFgAndGameBgCpuMode();
|
|
extern "C" bool APS5_VABI sceShellCoreUtilIsImposeScreenOverlaid();
|
|
extern "C" bool APS5_VABI sceShellCoreUtilIsScreenSaverOn();
|
|
extern "C" bool APS5_VABI sceSystemServiceIsScreenSaverOn();
|
|
extern "C" bool APS5_VABI sceSystemStateMgrIsShellUIShutdownInProgress();
|
|
extern "C" int APS5_VABI sceShellCoreUtilGetSocialScreenStatus(bool* active);
|
|
extern "C" int APS5_VABI sceShellCoreUtilIsEyeToEyeDistanceAdjusted(std::uint32_t userId, std::uint8_t* adjusted);
|
|
extern "C" int APS5_VABI sceSystemServiceIsEyeToEyeDistanceAdjusted(std::uint32_t userId, std::uint8_t* adjusted);
|
|
|
|
namespace {
|
|
|
|
constexpr auto LOGGED_IN_USER = static_cast<std::uint32_t>(USER_SERVICE_INITIAL_USER_ID);
|
|
|
|
int failures = 0;
|
|
|
|
template<typename TCall>
|
|
void Case(const char* name, TCall call) {
|
|
try {
|
|
if (call()) return;
|
|
std::printf("%s: wrong answer\n", name);
|
|
} catch (const std::exception& error) {
|
|
std::printf("%s: %s\n", name, error.what());
|
|
}
|
|
++failures;
|
|
}
|
|
|
|
template<typename TException, typename TCall>
|
|
bool Throws(TCall call) {
|
|
try {
|
|
static_cast<void>(call());
|
|
} catch (const TException&) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TestSuspend() {
|
|
Case("sceLncUtilBlockAppSuspend", [] {
|
|
return sceLncUtilBlockAppSuspend("saving") == SYSTEM_SERVICE_OK && sceLncUtilBlockAppSuspend("saving") == SYSTEM_SERVICE_OK;
|
|
});
|
|
Case("sceLncUtilUnblockAppSuspend", [] {
|
|
return sceLncUtilUnblockAppSuspend("saving") == SYSTEM_SERVICE_OK && sceLncUtilUnblockAppSuspend("saving") == SYSTEM_SERVICE_OK &&
|
|
Throws<std::logic_error>([] { return sceLncUtilUnblockAppSuspend("saving"); });
|
|
});
|
|
Case("sceLncUtilBlockAppSuspend null reason", [] {
|
|
return Throws<std::invalid_argument>([] { return sceLncUtilBlockAppSuspend(nullptr); }) &&
|
|
Throws<std::invalid_argument>([] { return sceLncUtilUnblockAppSuspend(nullptr); });
|
|
});
|
|
Case("sceLncUtilEnableSuspendNotification", [] {
|
|
return sceLncUtilEnableSuspendNotification() == SYSTEM_SERVICE_OK && sceLncUtilEnableSuspendNotification() == SYSTEM_SERVICE_OK;
|
|
});
|
|
Case("sceLncUtilDisableSuspendNotification", [] {
|
|
return sceLncUtilDisableSuspendNotification() == SYSTEM_SERVICE_OK && sceLncUtilDisableSuspendNotification() == SYSTEM_SERVICE_OK;
|
|
});
|
|
Case("sceSystemServiceEnableSuspendNotification", [] {
|
|
return sceSystemServiceEnableSuspendNotification() == sceLncUtilEnableSuspendNotification();
|
|
});
|
|
Case("sceSystemServiceDisableSuspendNotification", [] {
|
|
return sceSystemServiceDisableSuspendNotification() == sceLncUtilDisableSuspendNotification();
|
|
});
|
|
}
|
|
|
|
template<typename TCall>
|
|
bool ReportsInactive(TCall call) {
|
|
bool active = true;
|
|
return call(&active) == SYSTEM_SERVICE_OK && !active;
|
|
}
|
|
|
|
template<typename TCall>
|
|
bool RefusesNullOutput(TCall call) {
|
|
try {
|
|
static_cast<void>(call());
|
|
} catch (const std::runtime_error& error) {
|
|
return std::string_view(error.what()).find("null output") != std::string_view::npos;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TestSessions() {
|
|
Case("sceShellCoreUtilGetRemotePlayStatus", [] { return ReportsInactive(sceShellCoreUtilGetRemotePlayStatus); });
|
|
Case("sceShellCoreUtilGetRemotePlayStatus null output", [] {
|
|
return RefusesNullOutput([] { return sceShellCoreUtilGetRemotePlayStatus(nullptr); });
|
|
});
|
|
Case("sceSystemServiceGetRemoteplayStatus", [] {
|
|
return ReportsInactive(sceSystemServiceGetRemoteplayStatus) && sceSystemServiceGetRemoteplayStatus(nullptr) == SYSTEM_SERVICE_ERROR_PARAMETER;
|
|
});
|
|
Case("sceShellCoreUtilGetSharePlayStatus", [] { return ReportsInactive(sceShellCoreUtilGetSharePlayStatus); });
|
|
Case("sceShellCoreUtilGetSharePlayStatus null output", [] {
|
|
return RefusesNullOutput([] { return sceShellCoreUtilGetSharePlayStatus(nullptr); });
|
|
});
|
|
Case("sceShellCoreUtilGetGameLiveStreamingStatus", [] { return ReportsInactive(sceShellCoreUtilGetGameLiveStreamingStatus); });
|
|
Case("sceShellCoreUtilGetGameLiveStreamingStatus null output", [] {
|
|
return RefusesNullOutput([] { return sceShellCoreUtilGetGameLiveStreamingStatus(nullptr); });
|
|
});
|
|
Case("sceShellCoreUtilIsGameLiveStreamingOnAir", [] { return !sceShellCoreUtilIsGameLiveStreamingOnAir(); });
|
|
Case("sceSystemServiceIsGameLiveStreamingOnAir", [] {
|
|
return !sceSystemServiceIsGameLiveStreamingOnAir() && sceSystemServiceIsGameLiveStreamingOnAir() == sceShellCoreUtilIsGameLiveStreamingOnAir();
|
|
});
|
|
}
|
|
|
|
template<typename TCall>
|
|
bool ReportsNotAdjusted(TCall call) {
|
|
const auto user = LOGGED_IN_USER;
|
|
std::uint8_t adjusted = 0xff;
|
|
if (call(user, &adjusted) != SYSTEM_SERVICE_OK || adjusted != 0) return false;
|
|
for (const auto other : {0u, user + 1, static_cast<std::uint32_t>(USER_SERVICE_USER_ID_INVALID)}) {
|
|
adjusted = 0xff;
|
|
if (!Throws<std::invalid_argument>([&] { return call(other, &adjusted); }) || adjusted != 0xff) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TestShell() {
|
|
Case("sceLncUtilIsShellUiFgAndGameBgCpuMode", [] { return !sceLncUtilIsShellUiFgAndGameBgCpuMode(); });
|
|
Case("sceSystemServiceIsShellUiFgAndGameBgCpuMode", [] {
|
|
return !sceSystemServiceIsShellUiFgAndGameBgCpuMode() && sceSystemServiceIsShellUiFgAndGameBgCpuMode() == sceLncUtilIsShellUiFgAndGameBgCpuMode();
|
|
});
|
|
Case("sceShellCoreUtilIsImposeScreenOverlaid", [] { return !sceShellCoreUtilIsImposeScreenOverlaid(); });
|
|
Case("sceShellCoreUtilIsScreenSaverOn", [] { return !sceShellCoreUtilIsScreenSaverOn(); });
|
|
Case("sceSystemServiceIsScreenSaverOn", [] {
|
|
return !sceSystemServiceIsScreenSaverOn() && sceSystemServiceIsScreenSaverOn() == sceShellCoreUtilIsScreenSaverOn();
|
|
});
|
|
Case("sceSystemStateMgrIsShellUIShutdownInProgress", [] { return !sceSystemStateMgrIsShellUIShutdownInProgress(); });
|
|
Case("sceShellCoreUtilGetSocialScreenStatus", [] { return ReportsInactive(sceShellCoreUtilGetSocialScreenStatus); });
|
|
Case("sceShellCoreUtilGetSocialScreenStatus null output", [] {
|
|
return RefusesNullOutput([] { return sceShellCoreUtilGetSocialScreenStatus(nullptr); });
|
|
});
|
|
Case("sceShellCoreUtilIsEyeToEyeDistanceAdjusted", [] { return ReportsNotAdjusted(sceShellCoreUtilIsEyeToEyeDistanceAdjusted); });
|
|
Case("sceShellCoreUtilIsEyeToEyeDistanceAdjusted null output", [] {
|
|
return RefusesNullOutput([] { return sceShellCoreUtilIsEyeToEyeDistanceAdjusted(LOGGED_IN_USER, nullptr); });
|
|
});
|
|
Case("sceSystemServiceIsEyeToEyeDistanceAdjusted", [] {
|
|
return ReportsNotAdjusted(sceSystemServiceIsEyeToEyeDistanceAdjusted) &&
|
|
sceSystemServiceIsEyeToEyeDistanceAdjusted(LOGGED_IN_USER, nullptr) == SYSTEM_SERVICE_ERROR_PARAMETER;
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
const std::string_view mode = argc > 1 ? argv[1] : "";
|
|
if (mode == "suspend") TestSuspend();
|
|
else if (mode == "sessions") TestSessions();
|
|
else if (mode == "shell") TestShell();
|
|
else return 2;
|
|
if (failures == 0) std::printf("all cases passed\n");
|
|
return failures == 0 ? 0 : 1;
|
|
}
|