yuzutest.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2019 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include "common/string_util.h"
  6. #include "core/hle/ipc_helpers.h"
  7. #include "core/hle/service/service.h"
  8. #include "core/hle/service/sm/sm.h"
  9. #include "yuzu_tester/service/yuzutest.h"
  10. namespace Service::Yuzu {
  11. constexpr u64 SERVICE_VERSION = 0x00000002;
  12. class YuzuTest final : public ServiceFramework<YuzuTest> {
  13. public:
  14. explicit YuzuTest(std::string data,
  15. std::function<void(std::vector<TestResult>)> finish_callback)
  16. : ServiceFramework{"yuzutest"}, data(std::move(data)),
  17. finish_callback(std::move(finish_callback)) {
  18. static const FunctionInfo functions[] = {
  19. {0, &YuzuTest::Initialize, "Initialize"},
  20. {1, &YuzuTest::GetServiceVersion, "GetServiceVersion"},
  21. {2, &YuzuTest::GetData, "GetData"},
  22. {10, &YuzuTest::StartIndividual, "StartIndividual"},
  23. {20, &YuzuTest::FinishIndividual, "FinishIndividual"},
  24. {100, &YuzuTest::ExitProgram, "ExitProgram"},
  25. };
  26. RegisterHandlers(functions);
  27. }
  28. private:
  29. void Initialize(Kernel::HLERequestContext& ctx) {
  30. LOG_DEBUG(Frontend, "called");
  31. IPC::ResponseBuilder rb{ctx, 2};
  32. rb.Push(RESULT_SUCCESS);
  33. }
  34. void GetServiceVersion(Kernel::HLERequestContext& ctx) {
  35. LOG_DEBUG(Frontend, "called");
  36. IPC::ResponseBuilder rb{ctx, 4};
  37. rb.Push(RESULT_SUCCESS);
  38. rb.Push(SERVICE_VERSION);
  39. }
  40. void GetData(Kernel::HLERequestContext& ctx) {
  41. LOG_DEBUG(Frontend, "called");
  42. const auto size = ctx.GetWriteBufferSize();
  43. const auto write_size = std::min(size, data.size());
  44. ctx.WriteBuffer(data.data(), write_size);
  45. IPC::ResponseBuilder rb{ctx, 3};
  46. rb.Push(RESULT_SUCCESS);
  47. rb.Push<u32>(static_cast<u32>(write_size));
  48. }
  49. void StartIndividual(Kernel::HLERequestContext& ctx) {
  50. const auto name_raw = ctx.ReadBuffer();
  51. const auto name = Common::StringFromFixedZeroTerminatedBuffer(
  52. reinterpret_cast<const char*>(name_raw.data()), name_raw.size());
  53. LOG_DEBUG(Frontend, "called, name={}", name);
  54. IPC::ResponseBuilder rb{ctx, 2};
  55. rb.Push(RESULT_SUCCESS);
  56. }
  57. void FinishIndividual(Kernel::HLERequestContext& ctx) {
  58. IPC::RequestParser rp{ctx};
  59. const auto code = rp.PopRaw<u32>();
  60. const auto result_data_raw = ctx.ReadBuffer();
  61. const auto test_name_raw = ctx.ReadBuffer(1);
  62. const auto data = Common::StringFromFixedZeroTerminatedBuffer(
  63. reinterpret_cast<const char*>(result_data_raw.data()), result_data_raw.size());
  64. const auto test_name = Common::StringFromFixedZeroTerminatedBuffer(
  65. reinterpret_cast<const char*>(test_name_raw.data()), test_name_raw.size());
  66. LOG_INFO(Frontend, "called, result_code={:08X}, data={}, name={}", code, data, test_name);
  67. results.push_back({code, data, test_name});
  68. IPC::ResponseBuilder rb{ctx, 2};
  69. rb.Push(RESULT_SUCCESS);
  70. }
  71. void ExitProgram(Kernel::HLERequestContext& ctx) {
  72. LOG_DEBUG(Frontend, "called");
  73. IPC::ResponseBuilder rb{ctx, 2};
  74. rb.Push(RESULT_SUCCESS);
  75. finish_callback(std::move(results));
  76. }
  77. std::string data;
  78. std::vector<TestResult> results;
  79. std::function<void(std::vector<TestResult>)> finish_callback;
  80. };
  81. void InstallInterfaces(SM::ServiceManager& sm, std::string data,
  82. std::function<void(std::vector<TestResult>)> finish_callback) {
  83. std::make_shared<YuzuTest>(data, finish_callback)->InstallAsService(sm);
  84. }
  85. } // namespace Service::Yuzu