backend.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2019 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <functional>
  6. #include <optional>
  7. #include <string>
  8. #include <string_view>
  9. #include "common/common_types.h"
  10. #include "core/file_sys/vfs_types.h"
  11. #include "core/hle/kernel/readable_event.h"
  12. #include "core/hle/kernel/writable_event.h"
  13. #include "core/hle/result.h"
  14. namespace Service::BCAT {
  15. struct DeliveryCacheProgressImpl;
  16. using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>;
  17. using Passphrase = std::array<u8, 0x20>;
  18. struct TitleIDVersion {
  19. u64 title_id;
  20. u64 build_id;
  21. };
  22. using DirectoryName = std::array<char, 0x20>;
  23. using FileName = std::array<char, 0x20>;
  24. struct DeliveryCacheProgressImpl {
  25. enum class Status : s32 {
  26. None = 0x0,
  27. Queued = 0x1,
  28. Connecting = 0x2,
  29. ProcessingDataList = 0x3,
  30. Downloading = 0x4,
  31. Committing = 0x5,
  32. Done = 0x9,
  33. };
  34. Status status;
  35. ResultCode result = RESULT_SUCCESS;
  36. DirectoryName current_directory;
  37. FileName current_file;
  38. s64 current_downloaded_bytes; ///< Bytes downloaded on current file.
  39. s64 current_total_bytes; ///< Bytes total on current file.
  40. s64 total_downloaded_bytes; ///< Bytes downloaded on overall download.
  41. s64 total_bytes; ///< Bytes total on overall download.
  42. INSERT_PADDING_BYTES(
  43. 0x198); ///< Appears to be unused in official code, possibly reserved for future use.
  44. };
  45. static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200,
  46. "DeliveryCacheProgressImpl has incorrect size.");
  47. // A class to manage the signalling to the game about BCAT download progress.
  48. // Some of this class is implemented in module.cpp to avoid exposing the implementation structure.
  49. class ProgressServiceBackend {
  50. friend class IBcatService;
  51. public:
  52. // Clients should call this with true if any of the functions are going to be called from a
  53. // non-HLE thread and this class need to lock the hle mutex. (default is false)
  54. void SetNeedHLELock(bool need);
  55. // Sets the number of bytes total in the entire download.
  56. void SetTotalSize(u64 size);
  57. // Notifies the application that the backend has started connecting to the server.
  58. void StartConnecting();
  59. // Notifies the application that the backend has begun accumulating and processing metadata.
  60. void StartProcessingDataList();
  61. // Notifies the application that a file is starting to be downloaded.
  62. void StartDownloadingFile(std::string_view dir_name, std::string_view file_name, u64 file_size);
  63. // Updates the progress of the current file to the size passed.
  64. void UpdateFileProgress(u64 downloaded);
  65. // Notifies the application that the current file has completed download.
  66. void FinishDownloadingFile();
  67. // Notifies the application that all files in this directory have completed and are being
  68. // finalized.
  69. void CommitDirectory(std::string_view dir_name);
  70. // Notifies the application that the operation completed with result code result.
  71. void FinishDownload(ResultCode result);
  72. private:
  73. explicit ProgressServiceBackend(std::string_view event_name);
  74. Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent() const;
  75. DeliveryCacheProgressImpl& GetImpl();
  76. void SignalUpdate() const;
  77. DeliveryCacheProgressImpl impl;
  78. Kernel::EventPair event;
  79. bool need_hle_lock = false;
  80. };
  81. // A class representing an abstract backend for BCAT functionality.
  82. class Backend {
  83. public:
  84. explicit Backend(DirectoryGetter getter);
  85. virtual ~Backend();
  86. // Called when the backend is needed to synchronize the data for the game with title ID and
  87. // version in title. A ProgressServiceBackend object is provided to alert the application of
  88. // status.
  89. virtual bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) = 0;
  90. // Very similar to Synchronize, but only for the directory provided. Backends should not alter
  91. // the data for any other directories.
  92. virtual bool SynchronizeDirectory(TitleIDVersion title, std::string name,
  93. ProgressServiceBackend& progress) = 0;
  94. // Removes all cached data associated with title id provided.
  95. virtual bool Clear(u64 title_id) = 0;
  96. // Sets the BCAT Passphrase to be used with the associated title ID.
  97. virtual void SetPassphrase(u64 title_id, const Passphrase& passphrase) = 0;
  98. // Gets the launch parameter used by AM associated with the title ID and version provided.
  99. virtual std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) = 0;
  100. protected:
  101. DirectoryGetter dir_getter;
  102. };
  103. // A backend of BCAT that provides no operation.
  104. class NullBackend : public Backend {
  105. public:
  106. explicit NullBackend(const DirectoryGetter& getter);
  107. ~NullBackend() override;
  108. bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
  109. bool SynchronizeDirectory(TitleIDVersion title, std::string name,
  110. ProgressServiceBackend& progress) override;
  111. bool Clear(u64 title_id) override;
  112. void SetPassphrase(u64 title_id, const Passphrase& passphrase) override;
  113. std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
  114. };
  115. std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter);
  116. } // namespace Service::BCAT