diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 0f9894b7..d0aea2af 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -292,6 +292,7 @@ add_library(skyline SHARED ${source_DIR}/skyline/applet/controller_applet.cpp ${source_DIR}/skyline/applet/error_applet.cpp ${source_DIR}/skyline/applet/player_select_applet.cpp + ${source_DIR}/skyline/applet/web_applet.cpp ${source_DIR}/skyline/applet/swkbd/software_keyboard_applet.cpp ${source_DIR}/skyline/applet/swkbd/software_keyboard_config.cpp ${source_DIR}/skyline/services/codec/IHardwareOpusDecoder.cpp diff --git a/app/src/main/cpp/skyline/applet/applet_creator.cpp b/app/src/main/cpp/skyline/applet/applet_creator.cpp index 07a15fd0..9243c42e 100644 --- a/app/src/main/cpp/skyline/applet/applet_creator.cpp +++ b/app/src/main/cpp/skyline/applet/applet_creator.cpp @@ -5,6 +5,7 @@ #include "controller_applet.h" #include "error_applet.h" #include "player_select_applet.h" +#include "web_applet.h" #include "swkbd/software_keyboard_applet.h" namespace skyline::applet { @@ -23,6 +24,8 @@ namespace skyline::applet { return std::make_shared(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode); case AppletId::LibraryAppletError: return std::make_shared(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode); + case AppletId::LibraryAppletOfflineWeb: + return std::make_shared(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode); default: throw exception{"Unimplemented Applet: 0x{:X} ({})", static_cast(appletId), ToString(appletId)}; } diff --git a/app/src/main/cpp/skyline/applet/web_applet.cpp b/app/src/main/cpp/skyline/applet/web_applet.cpp new file mode 100644 index 00000000..c876f45b --- /dev/null +++ b/app/src/main/cpp/skyline/applet/web_applet.cpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) +// Copyright © 2020 yuzu Emulator Project (https://github.com/yuzu-emu/) + +#include +#include +#include +#include +#include "web_applet.h" + +namespace skyline::applet { + WebApplet::WebApplet(const DeviceState &state, + service::ServiceManager &manager, + std::shared_ptr onAppletStateChanged, + std::shared_ptr onNormalDataPushFromApplet, + std::shared_ptr onInteractiveDataPushFromApplet, + service::applet::LibraryAppletMode appletMode) + : IApplet{state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode} {} + + Result WebApplet::Start() { + auto commonArg{PopNormalInput()}; + auto argHeader{PopNormalInput()}; + + if ((commonArg.apiVersion >= 0x80000 && argHeader.shimKind == ShimKind::Web) || (commonArg.apiVersion >= 0x30000 && argHeader.shimKind == ShimKind::Share)) + Logger::Error("OfflineWeb TLV output is unsupported!"); + + PushNormalDataAndSignal(std::make_shared>(state, manager, WebCommonReturnValue{ + .exitReason = WebExitReason::WindowClosed, + .lastUrl = {'h', 't', 't', 'p', ':', '/', '/', 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', '/'}, + .lastUrlSize = 17 + })); + + // Notify the guest that we've finished running + onAppletStateChanged->Signal(); + return {}; + } + + Result WebApplet::GetResult() { + return {}; + } + + void WebApplet::PushNormalDataToApplet(std::shared_ptr data) { + PushNormalInput(data); + } + + void WebApplet::PushInteractiveDataToApplet(std::shared_ptr data) {} +} diff --git a/app/src/main/cpp/skyline/applet/web_applet.h b/app/src/main/cpp/skyline/applet/web_applet.h new file mode 100644 index 00000000..ab00d7e6 --- /dev/null +++ b/app/src/main/cpp/skyline/applet/web_applet.h @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) +// Copyright © 2020 Ryujinx Team and Contributors (https://github.com/ryujinx/) + +#pragma once + +#include + +namespace skyline::applet { + /** + * @brief The Web applet is utilized by the guest to display web pages using the built-in web browser + */ + class WebApplet : public service::am::IApplet, service::am::EnableNormalQueue { + private: + #pragma pack(push, 1) + + /** + * @brief Type of web-applet to launch + * @url https://switchbrew.org/wiki/Internet_Browser#ShimKind + */ + enum class ShimKind : u32 { + Shop = 1, + Login = 2, + Offline = 3, + Share = 4, + Web = 5, + Wifi = 6, + Lobby = 7, + Lhub = 8, + }; + + enum class WebExitReason : u32 { + EndButtonPressed = 0, + BackButtonPressed = 1, + ExitRequested = 2, + CallbackURL = 3, + WindowClosed = 4, + ErrorDialog = 7, + }; + + /** + * @brief Common return value struct for all web-applet commands + */ + struct WebCommonReturnValue { + WebExitReason exitReason; + u32 _pad_; + std::array lastUrl; + u64 lastUrlSize; + }; + static_assert(sizeof(WebCommonReturnValue) == 0x1010); + + /** + * @brief The input data for the web-applet + */ + struct WebArgHeader { + u16 count; + u16 _pad_; + ShimKind shimKind; + }; + + #pragma pack(pop) + + + public: + WebApplet(const DeviceState &state, service::ServiceManager &manager, std::shared_ptr onAppletStateChanged, std::shared_ptr onNormalDataPushFromApplet, std::shared_ptr onInteractiveDataPushFromApplet, service::applet::LibraryAppletMode appletMode); + + Result Start() override; + + Result GetResult() override; + + void PushNormalDataToApplet(std::shared_ptr data) override; + + void PushInteractiveDataToApplet(std::shared_ptr data) override; + }; +}