From 699900eed0fd25d0a60521e443d0d20e818c86d2 Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Wed, 21 Nov 2018 21:20:02 -0500
Subject: [PATCH 1/2] applets: Add StubApplet This will log all data it
 receives, log all calls to its methods and push dummy data into both channels
 on execution.

---
 src/core/CMakeLists.txt                       |  2 +
 .../hle/service/am/applets/stub_applet.cpp    | 65 +++++++++++++++++++
 src/core/hle/service/am/applets/stub_applet.h | 31 +++++++++
 3 files changed, 98 insertions(+)
 create mode 100644 src/core/hle/service/am/applets/stub_applet.cpp
 create mode 100644 src/core/hle/service/am/applets/stub_applet.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a355eaca64..c100340d02 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -156,6 +156,8 @@ add_library(core STATIC
     hle/service/am/applets/applets.h
     hle/service/am/applets/software_keyboard.cpp
     hle/service/am/applets/software_keyboard.h
+    hle/service/am/applets/stub_applet.cpp
+    hle/service/am/applets/stub_applet.h
     hle/service/am/idle.cpp
     hle/service/am/idle.h
     hle/service/am/omm.cpp
diff --git a/src/core/hle/service/am/applets/stub_applet.cpp b/src/core/hle/service/am/applets/stub_applet.cpp
new file mode 100644
index 0000000000..c9bd3d973c
--- /dev/null
+++ b/src/core/hle/service/am/applets/stub_applet.cpp
@@ -0,0 +1,65 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/hex_util.h"
+#include "core/hle/service/am/applets/stub_applet.h"
+
+namespace Service::AM::Applets {
+
+static void LogCurrentStorage(AppletDataBroker& broker, std::string prefix) {
+    std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
+    for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
+        const auto data = storage->GetData();
+        LOG_INFO(Service_AM,
+                 "called (STUBBED), during {} recieved normal data with size={:08X}, data={}",
+                 prefix, data.size(), Common::HexVectorToString(data));
+    }
+
+    storage = broker.PopInteractiveDataToApplet();
+    for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
+        const auto data = storage->GetData();
+        LOG_INFO(Service_AM,
+                 "called (STUBBED), during {} recieved interactive data with size={:08X}, data={}",
+                 prefix, data.size(), Common::HexVectorToString(data));
+    }
+}
+
+StubApplet::StubApplet() = default;
+
+StubApplet::~StubApplet() = default;
+
+void StubApplet::Initialize() {
+    LOG_WARNING(Service_AM, "called (STUBBED)");
+    Applet::Initialize();
+    LogCurrentStorage(broker, "Initialize");
+}
+
+bool StubApplet::TransactionComplete() const {
+    LOG_WARNING(Service_AM, "called (STUBBED)");
+    return true;
+}
+
+ResultCode StubApplet::GetStatus() const {
+    LOG_WARNING(Service_AM, "called (STUBBED)");
+    return RESULT_SUCCESS;
+}
+
+void StubApplet::ExecuteInteractive() {
+    LOG_WARNING(Service_AM, "called (STUBBED)");
+    LogCurrentStorage(broker, "ExecuteInteractive");
+
+    broker.PushNormalDataFromApplet(IStorage{std::vector<u8>(0x1000)});
+    broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)});
+    broker.SignalStateChanged();
+}
+
+void StubApplet::Execute() {
+    LOG_WARNING(Service_AM, "called (STUBBED)");
+    LogCurrentStorage(broker, "Execute");
+
+    broker.PushNormalDataFromApplet(IStorage{std::vector<u8>(0x1000)});
+    broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)});
+    broker.SignalStateChanged();
+}
+} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/stub_applet.h b/src/core/hle/service/am/applets/stub_applet.h
new file mode 100644
index 0000000000..41add5fe6a
--- /dev/null
+++ b/src/core/hle/service/am/applets/stub_applet.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <string>
+#include <vector>
+
+#include "common/common_funcs.h"
+#include "common/swap.h"
+#include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applets/applets.h"
+
+namespace Service::AM::Applets {
+
+class StubApplet final : public Applet {
+public:
+    StubApplet();
+    ~StubApplet() override;
+
+    void Initialize() override;
+
+    bool TransactionComplete() const override;
+    ResultCode GetStatus() const override;
+    void ExecuteInteractive() override;
+    void Execute() override;
+};
+
+} // namespace Service::AM::Applets

From f820e58be4532d7c845c828ba6ec609a5b277723 Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Thu, 22 Nov 2018 15:58:00 -0500
Subject: [PATCH 2/2] am: Return StubApplet instead of nullptr when AppletId
 not found

---
 src/core/hle/service/am/am.cpp                  | 10 ++++++----
 src/core/hle/service/am/applets/stub_applet.cpp |  5 +++++
 src/core/hle/service/am/applets/stub_applet.h   |  7 -------
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 11181a0af2..f4127701fc 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -6,8 +6,6 @@
 #include <cinttypes>
 #include <cstring>
 #include <stack>
-#include "applets/applets.h"
-#include "applets/software_keyboard.h"
 #include "audio_core/audio_renderer.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
@@ -18,6 +16,9 @@
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_oe.h"
+#include "core/hle/service/am/applets/applets.h"
+#include "core/hle/service/am/applets/software_keyboard.h"
+#include "core/hle/service/am/applets/stub_applet.h"
 #include "core/hle/service/am/idle.h"
 #include "core/hle/service/am/omm.h"
 #include "core/hle/service/am/spsm.h"
@@ -761,8 +762,9 @@ static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) {
     case AppletId::SoftwareKeyboard:
         return std::make_shared<Applets::SoftwareKeyboard>();
     default:
-        UNREACHABLE_MSG("Unimplemented AppletId [{:08X}]!", static_cast<u32>(id));
-        return nullptr;
+        LOG_ERROR(Service_AM, "Unimplemented AppletId [{:08X}]! -- Falling back to stub!",
+                  static_cast<u32>(id));
+        return std::make_shared<Applets::StubApplet>();
     }
 }
 
diff --git a/src/core/hle/service/am/applets/stub_applet.cpp b/src/core/hle/service/am/applets/stub_applet.cpp
index c9bd3d973c..ed166b87d1 100644
--- a/src/core/hle/service/am/applets/stub_applet.cpp
+++ b/src/core/hle/service/am/applets/stub_applet.cpp
@@ -2,7 +2,12 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <string>
+
 #include "common/hex_util.h"
+#include "common/logging/log.h"
+#include "core/hle/result.h"
+#include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applets/stub_applet.h"
 
 namespace Service::AM::Applets {
diff --git a/src/core/hle/service/am/applets/stub_applet.h b/src/core/hle/service/am/applets/stub_applet.h
index 41add5fe6a..7d8dc968dd 100644
--- a/src/core/hle/service/am/applets/stub_applet.h
+++ b/src/core/hle/service/am/applets/stub_applet.h
@@ -4,13 +4,6 @@
 
 #pragma once
 
-#include <array>
-#include <string>
-#include <vector>
-
-#include "common/common_funcs.h"
-#include "common/swap.h"
-#include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applets/applets.h"
 
 namespace Service::AM::Applets {