applets: Save report on stubbed applet

This also reworks the applet data storage to be peekable.
This commit is contained in:
Zach Hilman 2019-05-17 21:47:07 -04:00
parent 186db894b9
commit bdc47693f1
4 changed files with 49 additions and 15 deletions

View File

@ -35,12 +35,27 @@ AppletDataBroker::AppletDataBroker() {
AppletDataBroker::~AppletDataBroker() = default; AppletDataBroker::~AppletDataBroker() = default;
AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
std::vector<std::vector<u8>> out_normal;
std::vector<std::vector<u8>> out_interactive;
for (const auto& storage : in_channel) {
out_normal.push_back(storage->GetData());
}
for (const auto& storage : in_interactive_channel) {
out_interactive.push_back(storage->GetData());
}
return {out_normal, out_interactive};
}
std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
if (out_channel.empty()) if (out_channel.empty())
return nullptr; return nullptr;
auto out = std::move(out_channel.front()); auto out = std::move(out_channel.front());
out_channel.pop(); out_channel.pop_front();
return out; return out;
} }
@ -49,7 +64,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() {
return nullptr; return nullptr;
auto out = std::move(in_channel.front()); auto out = std::move(in_channel.front());
in_channel.pop(); in_channel.pop_front();
return out; return out;
} }
@ -58,7 +73,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
return nullptr; return nullptr;
auto out = std::move(out_interactive_channel.front()); auto out = std::move(out_interactive_channel.front());
out_interactive_channel.pop(); out_interactive_channel.pop_front();
return out; return out;
} }
@ -67,25 +82,25 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
return nullptr; return nullptr;
auto out = std::move(in_interactive_channel.front()); auto out = std::move(in_interactive_channel.front());
in_interactive_channel.pop(); in_interactive_channel.pop_front();
return out; return out;
} }
void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { void AppletDataBroker::PushNormalDataFromGame(IStorage storage) {
in_channel.push(std::make_unique<IStorage>(storage)); in_channel.push_back(std::make_unique<IStorage>(storage));
} }
void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) {
out_channel.push(std::make_unique<IStorage>(storage)); out_channel.push_back(std::make_unique<IStorage>(storage));
pop_out_data_event.writable->Signal(); pop_out_data_event.writable->Signal();
} }
void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) {
in_interactive_channel.push(std::make_unique<IStorage>(storage)); in_interactive_channel.push_back(std::make_unique<IStorage>(storage));
} }
void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) {
out_interactive_channel.push(std::make_unique<IStorage>(storage)); out_interactive_channel.push_back(std::make_unique<IStorage>(storage));
pop_interactive_out_data_event.writable->Signal(); pop_interactive_out_data_event.writable->Signal();
} }
@ -189,7 +204,7 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
UNIMPLEMENTED_MSG( UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id)); static_cast<u8>(id));
return std::make_shared<StubApplet>(); return std::make_shared<StubApplet>(id);
} }
} }

View File

@ -54,6 +54,14 @@ public:
AppletDataBroker(); AppletDataBroker();
~AppletDataBroker(); ~AppletDataBroker();
struct RawChannelData {
std::vector<std::vector<u8>> normal;
std::vector<std::vector<u8>> interactive;
};
// Retrieves but does not pop the data sent to applet.
RawChannelData PeekDataToAppletForDebug() const;
std::unique_ptr<IStorage> PopNormalDataToGame(); std::unique_ptr<IStorage> PopNormalDataToGame();
std::unique_ptr<IStorage> PopNormalDataToApplet(); std::unique_ptr<IStorage> PopNormalDataToApplet();
@ -76,16 +84,16 @@ private:
// Queues are named from applet's perspective // Queues are named from applet's perspective
// PopNormalDataToApplet and PushNormalDataFromGame // PopNormalDataToApplet and PushNormalDataFromGame
std::queue<std::unique_ptr<IStorage>> in_channel; std::deque<std::unique_ptr<IStorage>> in_channel;
// PopNormalDataToGame and PushNormalDataFromApplet // PopNormalDataToGame and PushNormalDataFromApplet
std::queue<std::unique_ptr<IStorage>> out_channel; std::deque<std::unique_ptr<IStorage>> out_channel;
// PopInteractiveDataToApplet and PushInteractiveDataFromGame // PopInteractiveDataToApplet and PushInteractiveDataFromGame
std::queue<std::unique_ptr<IStorage>> in_interactive_channel; std::deque<std::unique_ptr<IStorage>> in_interactive_channel;
// PopInteractiveDataToGame and PushInteractiveDataFromApplet // PopInteractiveDataToGame and PushInteractiveDataFromApplet
std::queue<std::unique_ptr<IStorage>> out_interactive_channel; std::deque<std::unique_ptr<IStorage>> out_interactive_channel;
Kernel::EventPair state_changed_event; Kernel::EventPair state_changed_event;

View File

@ -13,6 +13,7 @@
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/general_backend.h" #include "core/hle/service/am/applets/general_backend.h"
#include "core/reporter.h"
namespace Service::AM::Applets { namespace Service::AM::Applets {
@ -83,13 +84,20 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged(); broker.SignalStateChanged();
} }
StubApplet::StubApplet() = default; StubApplet::StubApplet(AppletId id) : id(id) {}
StubApplet::~StubApplet() = default; StubApplet::~StubApplet() = default;
void StubApplet::Initialize() { void StubApplet::Initialize() {
LOG_WARNING(Service_AM, "called (STUBBED)"); LOG_WARNING(Service_AM, "called (STUBBED)");
Applet::Initialize(); Applet::Initialize();
const auto data = broker.PeekDataToAppletForDebug();
Core::System::GetInstance().GetReporter().SaveUnimplementedAppletReport(
static_cast<u32>(id), common_args.arguments_version, common_args.library_version,
common_args.theme_color, common_args.play_startup_sound, common_args.system_tick,
data.normal, data.interactive);
LogCurrentStorage(broker, "Initialize"); LogCurrentStorage(broker, "Initialize");
} }

View File

@ -34,7 +34,7 @@ private:
class StubApplet final : public Applet { class StubApplet final : public Applet {
public: public:
StubApplet(); StubApplet(AppletId id);
~StubApplet() override; ~StubApplet() override;
void Initialize() override; void Initialize() override;
@ -43,6 +43,9 @@ public:
ResultCode GetStatus() const override; ResultCode GetStatus() const override;
void ExecuteInteractive() override; void ExecuteInteractive() override;
void Execute() override; void Execute() override;
private:
AppletId id;
}; };
} // namespace Service::AM::Applets } // namespace Service::AM::Applets