mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			692 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			692 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2018 yuzu emulator team
 | 
						|
// Licensed under GPLv2 or any later version
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include <cinttypes>
 | 
						|
#include "core/file_sys/filesystem.h"
 | 
						|
#include "core/hle/ipc_helpers.h"
 | 
						|
#include "core/hle/kernel/event.h"
 | 
						|
#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/apm/apm.h"
 | 
						|
#include "core/hle/service/filesystem/filesystem.h"
 | 
						|
#include "core/hle/service/nvflinger/nvflinger.h"
 | 
						|
#include "core/hle/service/set/set.h"
 | 
						|
#include "core/settings.h"
 | 
						|
 | 
						|
namespace Service::AM {
 | 
						|
 | 
						|
IWindowController::IWindowController() : ServiceFramework("IWindowController") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "CreateWindow"},
 | 
						|
        {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
 | 
						|
        {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
 | 
						|
        {11, nullptr, "ReleaseForegroundRights"},
 | 
						|
        {12, nullptr, "RejectToChangeIntoBackground"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    IPC::ResponseBuilder rb{ctx, 4};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push<u64>(0);
 | 
						|
}
 | 
						|
 | 
						|
void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
IAudioController::IAudioController() : ServiceFramework("IAudioController") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
 | 
						|
        {1, &IAudioController::GetMainAppletExpectedMasterVolume,
 | 
						|
         "GetMainAppletExpectedMasterVolume"},
 | 
						|
        {2, &IAudioController::GetLibraryAppletExpectedMasterVolume,
 | 
						|
         "GetLibraryAppletExpectedMasterVolume"},
 | 
						|
        {3, nullptr, "ChangeMainAppletMasterVolume"},
 | 
						|
        {4, nullptr, "SetTransparentVolumeRate"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(volume);
 | 
						|
}
 | 
						|
 | 
						|
void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(volume);
 | 
						|
}
 | 
						|
 | 
						|
IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "GetLastForegroundCaptureImage"},
 | 
						|
        {1, nullptr, "UpdateLastForegroundCaptureImage"},
 | 
						|
        {2, nullptr, "GetLastApplicationCaptureImage"},
 | 
						|
        {3, nullptr, "GetCallerAppletCaptureImage"},
 | 
						|
        {4, nullptr, "UpdateCallerAppletCaptureImage"},
 | 
						|
        {5, nullptr, "GetLastForegroundCaptureImageEx"},
 | 
						|
        {6, nullptr, "GetLastApplicationCaptureImageEx"},
 | 
						|
        {7, nullptr, "GetCallerAppletCaptureImageEx"},
 | 
						|
        {8, nullptr, "TakeScreenShotOfOwnLayer"},  // 2.0.0+
 | 
						|
        {9, nullptr, "CopyBetweenCaptureBuffers"}, // 5.0.0+
 | 
						|
        {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
 | 
						|
        {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
 | 
						|
        {12, nullptr, "AcquireLastForegroundCaptureBuffer"},
 | 
						|
        {13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
 | 
						|
        {14, nullptr, "AcquireCallerAppletCaptureBuffer"},
 | 
						|
        {15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
 | 
						|
        {16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
 | 
						|
        {17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
 | 
						|
        {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
 | 
						|
        // 2.0.0+
 | 
						|
        {20, nullptr, "ClearCaptureBuffer"},
 | 
						|
        {21, nullptr, "ClearAppletTransitionBuffer"},
 | 
						|
        // 4.0.0+
 | 
						|
        {22, nullptr, "AcquireLastApplicationCaptureSharedBuffer"},
 | 
						|
        {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
 | 
						|
        {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
 | 
						|
        {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
 | 
						|
        {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"},
 | 
						|
        {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
 | 
						|
 | 
						|
ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
 | 
						|
    : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "Exit"},
 | 
						|
        {1, &ISelfController::LockExit, "LockExit"},
 | 
						|
        {2, &ISelfController::UnlockExit, "UnlockExit"},
 | 
						|
        {3, nullptr, "EnterFatalSection"},
 | 
						|
        {4, nullptr, "LeaveFatalSection"},
 | 
						|
        {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
 | 
						|
        {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
 | 
						|
        {11, &ISelfController::SetOperationModeChangedNotification,
 | 
						|
         "SetOperationModeChangedNotification"},
 | 
						|
        {12, &ISelfController::SetPerformanceModeChangedNotification,
 | 
						|
         "SetPerformanceModeChangedNotification"},
 | 
						|
        {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
 | 
						|
        {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
 | 
						|
        {15, nullptr, "SetScreenShotAppletIdentityInfo"},
 | 
						|
        {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
 | 
						|
        {17, nullptr, "SetControllerFirmwareUpdateSection"},
 | 
						|
        {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
 | 
						|
        {19, nullptr, "SetScreenShotImageOrientation"},
 | 
						|
        {20, nullptr, "SetDesirableKeyboardLayout"},
 | 
						|
        {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
 | 
						|
        {41, nullptr, "IsSystemBufferSharingEnabled"},
 | 
						|
        {42, nullptr, "GetSystemSharedLayerHandle"},
 | 
						|
        {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
 | 
						|
        {51, nullptr, "ApproveToDisplay"},
 | 
						|
        {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
 | 
						|
        {61, nullptr, "SetMediaPlaybackState"},
 | 
						|
        {62, nullptr, "SetIdleTimeDetectionExtension"},
 | 
						|
        {63, nullptr, "GetIdleTimeDetectionExtension"},
 | 
						|
        {64, nullptr, "SetInputDetectionSourceSet"},
 | 
						|
        {65, nullptr, "ReportUserIsActive"},
 | 
						|
        {66, nullptr, "GetCurrentIlluminance"},
 | 
						|
        {67, nullptr, "IsIlluminanceAvailable"},
 | 
						|
        {68, nullptr, "SetAutoSleepDisabled"},
 | 
						|
        {69, nullptr, "IsAutoSleepDisabled"},
 | 
						|
        {70, nullptr, "ReportMultimediaError"},
 | 
						|
        {80, nullptr, "SetWirelessPriorityMode"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
 | 
						|
    launchable_event =
 | 
						|
        Kernel::Event::Create(Kernel::ResetType::OneShot, "ISelfController:LaunchableEvent");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
 | 
						|
    // Takes 3 input u8s with each field located immediately after the previous u8, these are
 | 
						|
    // bool flags. No output.
 | 
						|
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
 | 
						|
    struct FocusHandlingModeParams {
 | 
						|
        u8 unknown0;
 | 
						|
        u8 unknown1;
 | 
						|
        u8 unknown2;
 | 
						|
    };
 | 
						|
    auto flags = rp.PopRaw<FocusHandlingModeParams>();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
 | 
						|
    bool flag = rp.Pop<bool>();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
 | 
						|
    bool flag = rp.Pop<bool>();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
 | 
						|
    // Takes 3 input u8s with each field located immediately after the previous u8, these are
 | 
						|
    // bool flags. No output.
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
 | 
						|
    bool enabled = rp.Pop<bool>();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
 | 
						|
    launchable_event->Signal();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.PushCopyObjects(launchable_event);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
 | 
						|
    // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
 | 
						|
    // in the Default display.
 | 
						|
    u64 display_id = nvflinger->OpenDisplay("Default");
 | 
						|
    u64 layer_id = nvflinger->CreateLayer(display_id);
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 4};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(layer_id);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
 | 
						|
        {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
 | 
						|
        {2, nullptr, "GetThisAppletKind"},
 | 
						|
        {3, nullptr, "AllowToEnterSleep"},
 | 
						|
        {4, nullptr, "DisallowToEnterSleep"},
 | 
						|
        {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
 | 
						|
        {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
 | 
						|
        {7, nullptr, "GetCradleStatus"},
 | 
						|
        {8, nullptr, "GetBootMode"},
 | 
						|
        {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
 | 
						|
        {10, nullptr, "RequestToAcquireSleepLock"},
 | 
						|
        {11, nullptr, "ReleaseSleepLock"},
 | 
						|
        {12, nullptr, "ReleaseSleepLockTransiently"},
 | 
						|
        {13, nullptr, "GetAcquiredSleepLockEvent"},
 | 
						|
        {20, nullptr, "PushToGeneralChannel"},
 | 
						|
        {30, nullptr, "GetHomeButtonReaderLockAccessor"},
 | 
						|
        {31, nullptr, "GetReaderLockAccessorEx"},
 | 
						|
        {40, nullptr, "GetCradleFwVersion"},
 | 
						|
        {50, nullptr, "IsVrModeEnabled"},
 | 
						|
        {51, nullptr, "SetVrModeEnabled"},
 | 
						|
        {52, nullptr, "SwitchLcdBacklight"},
 | 
						|
        {55, nullptr, "IsInControllerFirmwareUpdateSection"},
 | 
						|
        {60, nullptr, "GetDefaultDisplayResolution"},
 | 
						|
        {61, nullptr, "GetDefaultDisplayResolutionChangeEvent"},
 | 
						|
        {62, nullptr, "GetHdcpAuthenticationState"},
 | 
						|
        {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
 | 
						|
    event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
 | 
						|
}
 | 
						|
 | 
						|
void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
 | 
						|
    event->Signal();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.PushCopyObjects(event);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push<u32>(15);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(static_cast<u8>(FocusState::InFocus));
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
 | 
						|
    const bool use_docked_mode{Settings::values.use_docked_mode};
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
 | 
						|
    const bool use_docked_mode{Settings::values.use_docked_mode};
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
 | 
						|
                                             : APM::PerformanceMode::Handheld));
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
 | 
						|
public:
 | 
						|
    explicit ILibraryAppletAccessor() : ServiceFramework("ILibraryAppletAccessor") {
 | 
						|
        static const FunctionInfo functions[] = {
 | 
						|
            {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
 | 
						|
            {1, nullptr, "IsCompleted"},
 | 
						|
            {10, nullptr, "Start"},
 | 
						|
            {20, nullptr, "RequestExit"},
 | 
						|
            {25, nullptr, "Terminate"},
 | 
						|
            {30, nullptr, "GetResult"},
 | 
						|
            {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
 | 
						|
            {100, nullptr, "PushInData"},
 | 
						|
            {101, nullptr, "PopOutData"},
 | 
						|
            {102, nullptr, "PushExtraStorage"},
 | 
						|
            {103, nullptr, "PushInteractiveInData"},
 | 
						|
            {104, nullptr, "PopInteractiveOutData"},
 | 
						|
            {105, nullptr, "GetPopOutDataEvent"},
 | 
						|
            {106, nullptr, "GetPopInteractiveOutDataEvent"},
 | 
						|
            {110, nullptr, "NeedsToExitProcess"},
 | 
						|
            {120, nullptr, "GetLibraryAppletInfo"},
 | 
						|
            {150, nullptr, "RequestForAppletToGetForeground"},
 | 
						|
            {160, nullptr, "GetIndirectLayerConsumerHandle"},
 | 
						|
        };
 | 
						|
        RegisterHandlers(functions);
 | 
						|
 | 
						|
        state_changed_event = Kernel::Event::Create(Kernel::ResetType::OneShot,
 | 
						|
                                                    "ILibraryAppletAccessor:StateChangedEvent");
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
 | 
						|
        state_changed_event->Signal();
 | 
						|
 | 
						|
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
						|
        rb.Push(RESULT_SUCCESS);
 | 
						|
        rb.PushCopyObjects(state_changed_event);
 | 
						|
 | 
						|
        NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
    }
 | 
						|
 | 
						|
    Kernel::SharedPtr<Kernel::Event> state_changed_event;
 | 
						|
};
 | 
						|
 | 
						|
ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
 | 
						|
        {1, nullptr, "TerminateAllLibraryApplets"},
 | 
						|
        {2, nullptr, "AreAnyLibraryAppletsLeft"},
 | 
						|
        {10, nullptr, "CreateStorage"},
 | 
						|
        {11, nullptr, "CreateTransferMemoryStorage"},
 | 
						|
        {12, nullptr, "CreateHandleStorage"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
						|
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.PushIpcInterface<AM::ILibraryAppletAccessor>();
 | 
						|
 | 
						|
    NGLOG_DEBUG(Service_AM, "called");
 | 
						|
}
 | 
						|
 | 
						|
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
 | 
						|
public:
 | 
						|
    explicit IStorageAccessor(std::vector<u8> buffer)
 | 
						|
        : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
 | 
						|
        static const FunctionInfo functions[] = {
 | 
						|
            {0, &IStorageAccessor::GetSize, "GetSize"},
 | 
						|
            {10, nullptr, "Write"},
 | 
						|
            {11, &IStorageAccessor::Read, "Read"},
 | 
						|
        };
 | 
						|
        RegisterHandlers(functions);
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    std::vector<u8> buffer;
 | 
						|
 | 
						|
    void GetSize(Kernel::HLERequestContext& ctx) {
 | 
						|
        IPC::ResponseBuilder rb{ctx, 4};
 | 
						|
 | 
						|
        rb.Push(RESULT_SUCCESS);
 | 
						|
        rb.Push(static_cast<u64>(buffer.size()));
 | 
						|
 | 
						|
        NGLOG_DEBUG(Service_AM, "called");
 | 
						|
    }
 | 
						|
 | 
						|
    void Read(Kernel::HLERequestContext& ctx) {
 | 
						|
        IPC::RequestParser rp{ctx};
 | 
						|
 | 
						|
        u64 offset = rp.Pop<u64>();
 | 
						|
 | 
						|
        const size_t size{ctx.GetWriteBufferSize()};
 | 
						|
 | 
						|
        ASSERT(offset + size <= buffer.size());
 | 
						|
 | 
						|
        ctx.WriteBuffer(buffer.data() + offset, size);
 | 
						|
 | 
						|
        IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
 | 
						|
        rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
        NGLOG_DEBUG(Service_AM, "called");
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
class IStorage final : public ServiceFramework<IStorage> {
 | 
						|
public:
 | 
						|
    explicit IStorage(std::vector<u8> buffer)
 | 
						|
        : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
 | 
						|
        static const FunctionInfo functions[] = {
 | 
						|
            {0, &IStorage::Open, "Open"},
 | 
						|
            {1, nullptr, "OpenTransferStorage"},
 | 
						|
        };
 | 
						|
        RegisterHandlers(functions);
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    std::vector<u8> buffer;
 | 
						|
 | 
						|
    void Open(Kernel::HLERequestContext& ctx) {
 | 
						|
        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
						|
 | 
						|
        rb.Push(RESULT_SUCCESS);
 | 
						|
        rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
 | 
						|
 | 
						|
        NGLOG_DEBUG(Service_AM, "called");
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
 | 
						|
        {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
 | 
						|
        {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
 | 
						|
        {12, nullptr, "CreateApplicationAndRequestToStart"},
 | 
						|
        {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest,
 | 
						|
         "CreateApplicationAndRequestToStartForQuest"},
 | 
						|
        {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
 | 
						|
        {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
 | 
						|
        {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
 | 
						|
        {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
 | 
						|
        {24, nullptr, "GetLaunchStorageInfoForDebug"},
 | 
						|
        {25, nullptr, "ExtendSaveData"},
 | 
						|
        {26, nullptr, "GetSaveDataSize"},
 | 
						|
        {30, nullptr, "BeginBlockingHomeButtonShortAndLongPressed"},
 | 
						|
        {31, nullptr, "EndBlockingHomeButtonShortAndLongPressed"},
 | 
						|
        {32, nullptr, "BeginBlockingHomeButton"},
 | 
						|
        {33, nullptr, "EndBlockingHomeButton"},
 | 
						|
        {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
 | 
						|
        {50, nullptr, "GetPseudoDeviceId"},
 | 
						|
        {60, nullptr, "SetMediaPlaybackStateForApplication"},
 | 
						|
        {65, nullptr, "IsGamePlayRecordingSupported"},
 | 
						|
        {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
 | 
						|
        {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
 | 
						|
        {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
 | 
						|
        {70, nullptr, "RequestToShutdown"},
 | 
						|
        {71, nullptr, "RequestToReboot"},
 | 
						|
        {80, nullptr, "ExitAndRequestToShowThanksMessage"},
 | 
						|
        {90, nullptr, "EnableApplicationCrashReport"},
 | 
						|
        {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"},
 | 
						|
        {101, nullptr, "SetApplicationCopyrightImage"},
 | 
						|
        {102, nullptr, "SetApplicationCopyrightVisibility"},
 | 
						|
        {110, nullptr, "QueryApplicationPlayStatistics"},
 | 
						|
        {120, nullptr, "ExecuteProgram"},
 | 
						|
        {121, nullptr, "ClearUserChannel"},
 | 
						|
        {122, nullptr, "UnpopToUserChannel"},
 | 
						|
        {500, nullptr, "StartContinuousRecordingFlushForDebug"},
 | 
						|
        {1000, nullptr, "CreateMovieMaker"},
 | 
						|
        {1001, nullptr, "PrepareForJit"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
 | 
						|
    constexpr u8 data[0x88] = {
 | 
						|
        0xca, 0x97, 0x94, 0xc7, // Magic
 | 
						|
        1,    0,    0,    0,    // IsAccountSelected (bool)
 | 
						|
        1,    0,    0,    0,    // User Id (word 0)
 | 
						|
        0,    0,    0,    0,    // User Id (word 1)
 | 
						|
        0,    0,    0,    0,    // User Id (word 2)
 | 
						|
        0,    0,    0,    0     // User Id (word 3)
 | 
						|
    };
 | 
						|
 | 
						|
    std::vector<u8> buffer(data, data + sizeof(data));
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
						|
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.PushIpcInterface<AM::IStorage>(buffer);
 | 
						|
 | 
						|
    NGLOG_DEBUG(Service_AM, "called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
 | 
						|
    Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
    u128 uid = rp.PopRaw<u128>();
 | 
						|
 | 
						|
    NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 4};
 | 
						|
 | 
						|
    FileSys::Path unused;
 | 
						|
    auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused);
 | 
						|
    if (savedata.Failed()) {
 | 
						|
        // Create the save data and return an error indicating that the operation was performed.
 | 
						|
        FileSystem::FormatFileSystem(FileSystem::Type::SaveData);
 | 
						|
        // TODO(Subv): Find out the correct error code for this.
 | 
						|
        rb.Push(ResultCode(ErrorModule::FS, 40));
 | 
						|
    } else {
 | 
						|
        rb.Push(RESULT_SUCCESS);
 | 
						|
    }
 | 
						|
 | 
						|
    rb.Push<u64>(0);
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
 | 
						|
    // Takes an input u32 Result, no output.
 | 
						|
    // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
 | 
						|
 | 
						|
    IPC::RequestParser rp{ctx};
 | 
						|
    u32 result = rp.Pop<u32>();
 | 
						|
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 6};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push<u64>(1);
 | 
						|
    rb.Push<u64>(0);
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
 | 
						|
    // TODO(bunnei): This should be configurable
 | 
						|
    IPC::ResponseBuilder rb{ctx, 4};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US));
 | 
						|
    NGLOG_DEBUG(Service_AM, "called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 3};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
 | 
						|
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
void InstallInterfaces(SM::ServiceManager& service_manager,
 | 
						|
                       std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
 | 
						|
    std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
 | 
						|
    std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
 | 
						|
}
 | 
						|
 | 
						|
IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
 | 
						|
        {11, nullptr, "LockForeground"},
 | 
						|
        {12, nullptr, "UnlockForeground"},
 | 
						|
        {20, nullptr, "PopFromGeneralChannel"},
 | 
						|
        {21, nullptr, "GetPopFromGeneralChannelEvent"},
 | 
						|
        {30, nullptr, "GetHomeButtonWriterLockAccessor"},
 | 
						|
        {31, nullptr, "GetWriterLockAccessorEx"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
 | 
						|
    IPC::ResponseBuilder rb{ctx, 2};
 | 
						|
    rb.Push(RESULT_SUCCESS);
 | 
						|
    NGLOG_WARNING(Service_AM, "(STUBBED) called");
 | 
						|
}
 | 
						|
 | 
						|
IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "RequestToEnterSleep"},
 | 
						|
        {1, nullptr, "EnterSleep"},
 | 
						|
        {2, nullptr, "StartSleepSequence"},
 | 
						|
        {3, nullptr, "StartShutdownSequence"},
 | 
						|
        {4, nullptr, "StartRebootSequence"},
 | 
						|
        {10, nullptr, "LoadAndApplyIdlePolicySettings"},
 | 
						|
        {11, nullptr, "NotifyCecSettingsChanged"},
 | 
						|
        {12, nullptr, "SetDefaultHomeButtonLongPressTime"},
 | 
						|
        {13, nullptr, "UpdateDefaultDisplayResolution"},
 | 
						|
        {14, nullptr, "ShouldSleepOnBoot"},
 | 
						|
        {15, nullptr, "GetHdcpAuthenticationFailedEvent"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "CreateApplication"},
 | 
						|
        {1, nullptr, "PopLaunchRequestedApplication"},
 | 
						|
        {10, nullptr, "CreateSystemApplication"},
 | 
						|
        {100, nullptr, "PopFloatingApplicationForDevelopment"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
 | 
						|
IProcessWindingController::IProcessWindingController()
 | 
						|
    : ServiceFramework("IProcessWindingController") {
 | 
						|
    static const FunctionInfo functions[] = {
 | 
						|
        {0, nullptr, "GetLaunchReason"},
 | 
						|
        {11, nullptr, "OpenCallingLibraryApplet"},
 | 
						|
        {21, nullptr, "PushContext"},
 | 
						|
        {22, nullptr, "PopContext"},
 | 
						|
        {23, nullptr, "CancelWindingReservation"},
 | 
						|
        {30, nullptr, "WindAndDoReserved"},
 | 
						|
        {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"},
 | 
						|
        {41, nullptr, "ReserveToStartAndWait"},
 | 
						|
    };
 | 
						|
    RegisterHandlers(functions);
 | 
						|
}
 | 
						|
} // namespace Service::AM
 |